Partage
  • Partager sur Facebook
  • Partager sur Twitter

Probleme avec un *pchar=entier

dans une sous fonction de la source de Openssl

Sujet résolu
    23 octobre 2008 à 11:16:03

    Bonjour à tous!

    Voila en étudiant la source de Openssl 098i (le dernier) je suis tombé sur une fonction qui provoquait des core dumped a n'en plus finir.
    Je l'ai décortiquée et j'ai pu voir que l'erreur est provoquée par ce simple petit bout de code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
    unsigned char *d;
    *d=14;
    printf("%x\n",d);
    return 1;
    
    }
    

    En fait j'ai l'impression que l'erreur vient de l'etoile.
    En effet ce code la fonctionne (pas de core dumped):
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
    unsigned char d;
    d=14;
    printf("%x\n",d);
    return 1;
    
    }
    

    Pourtant *d est bien un unsigned char non?
    Comment faire pour contourner le pbm en changeant le code un petit peu?
    Me manque t il une bibliotheque?



    Et pour info je vous envoie le code source de la fonction Openssl originale:
    /* class 0 is constructed
     * constructed == 2 for indefinite length constructed */
    void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
    	     int xclass)
    	{
    	unsigned char *p= *pp;
    	int i, ttag;
    
    	i=(constructed)?V_ASN1_CONSTRUCTED:0;
    	i|=(xclass&V_ASN1_PRIVATE);
    	if (tag < 31)
    		*(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG);
    	else
    		{
    		*(p++)=i|V_ASN1_PRIMITIVE_TAG; //!c'est cette ligne là qui provoque l'erreur!
    		for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
    		ttag = i;
    		while(i-- > 0)
    			{
    			p[i] = tag & 0x7f;
    			if(i != (ttag - 1)) p[i] |= 0x80;
    			tag >>= 7;
    			}
    		p += ttag;
    		}
    	if (constructed == 2)
    		*(p++)=0x80;
    	else
    		asn1_put_length(&p,length);
    	*pp=p;
    	}
    


    Voila, j'espere que je ne me suis pas trop mal exprimé. J'en ai peut etre trop mis? :euh:
    • Partager sur Facebook
    • Partager sur Twitter
      23 octobre 2008 à 11:29:20

      Bonjour,

      Citation : Cyrard

      [...] Je l'ai décortiquée et j'ai pu voir que l'erreur est provoquée par ce simple petit bout de code:

      #include <stdio.h>
      #include <string.h>
      
      int main(void)
      {
      unsigned char *d;
      *d=14;
      printf("%x\n",d);
      return 1;
      
      }
      

      Après avoir déclaré ton pointeur d, sur quoi pointe-t-il à ton avis ?
      • Partager sur Facebook
      • Partager sur Twitter
        23 octobre 2008 à 11:35:29

        Citation : Cyrard


        #include <stdio.h>
        #include <string.h>
        
        int main(void)
        {
        unsigned char *d;
        *d=14;
        printf("%x\n",d);
        return 1;
        
        }
        


        En fait j'ai l'impression que l'erreur vient de l'etoile.



        Oui, c'est une grossière erreur : dans le jargon, on dit que tu déréférences un pointeur non initialisé. Explication : à la ligne 6 de ton code tu alloues de l'espace mémoire pour un pointeur vers un char non signé et tu n'alloues rien pour ce futur char non signé. Or à la ligne suivante, tu places la valeur 14 à l'adresse qui figure dans le pointeur. Or, tu n'as pas réservé de place pour cette valeur, donc tu as une erreur de segmentation. Si tu veux remédier à cela, il te faut initialiser le pointeur d cad le faire pointer vers une adresse valide ie une zone mémoire pour laquelle tu auras alloué, soit statiquement (comme je vais faire ci-dessous) soit dynamiquement avec un appel de malloc().

        Autre chose, tu n'as pas le droit a priori d'écrire dans main() une instruction return 1.


        Voici un code qui corrige ton problème :

        #include <stdio.h>
        
        int main(void)
        {
          unsigned char a;
          unsigned char *d;
        
          d = &a; /* On initialise le pointeur */
          *d = 14; /* possible :  on écrit dans une zone allouée */
          printf("%x %x\n", *d, a);
        
          return 0;
        }
        
        • Partager sur Facebook
        • Partager sur Twitter
          23 octobre 2008 à 15:39:05

          Citation : Cyrard

          l'erreur est provoquée par ce simple petit bout de code:

          #include <stdio.h>
          #include <string.h>
          
          int main(void)
          {
          unsigned char *d;
          *d=14;
          printf("%x\n",d);
          return 1;
          
          }
          



          d est un pointeur non initialisé. sa valeur est indéterminée.
          *d invoque un comportement indéfini.

          d doit avoir une valeur valide avant d'être utilisé. Il peut aussi valoir NULL, dans ce cas, il est invalide, mais testable.

          Pour qu'un pointeur soit valide, il faut lui donner soit :

          - l'adresse d'une variable existante
          - la valeur d'un pointeur valide
          - la valeur retournée par malloc() et ses soeurs
          - Si il est de type FILE *, la valeur retournée par fopen().

          • Partager sur Facebook
          • Partager sur Twitter
          Music only !
            24 octobre 2008 à 10:35:44

            Alors là merci beaucoup à tous!
            En effet je viens de me rendre compte que mon pointeur n'était pas initialisé, chose que je devais faire avec un malloc avant d'utiliser la fonction openssl qui utilisait le pointeur ainsi initialisé. Maintenant ça marche!
            Grâce a vos réponses on ne peut plus pédagogiques et claires je viens de combler une de mes innombrables lacunes en langage C! ;-)
            Merci encore a tous les 3!
            • Partager sur Facebook
            • Partager sur Twitter

            Probleme avec un *pchar=entier

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown