IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

Corruption of the heap


Sujet :

MFC

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Par défaut Corruption of the heap
    Bonjour à tous,
    Lors de la phase de débogage, et en sortie de fonction, j'obtiens le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Windows has triggered a breakpoint in Interface.exe
    This may be due to a corruption of the heap, and indicates a bug ...patati, patata
    A quoi cela peut-il être dû ?

    Je précise que je travaille sous Visual Studio 2005.

    Voici le code qui pose problème. La fonction appelante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	if ((CDlgIdentification::Verification(m_strIdent,m_strPasswd)) == TRUE){
    et le code de la fonction Verification est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    bool CDlgIdentification::Verification(CString ident, CString passwd){
    	//Faire la vérification de l'identifiant et du mot de passe
    	std::ifstream fichier( "C:\\Temp\\passe.bin");
    	int truc;
        if ( fichier ) // ce test échoue si le fichier n'est pas ouvert
        {
            std::string ligne; // variable contenant chaque ligne lue
    		while ( std::getline( fichier, ligne ) ){
    			CCryptString OCrypt;
    			CString passwddec;
    			OCrypt.DecryptString((TCHAR *)ligne.c_str(), passwddec.GetBuffer(0),cryptkey); //décrypter la ligne lue
    			CString Cligne (ligne.c_str());//copier le string en CString
    			CString CligneTemp = Cligne;
    			char* pWord=strtok(passwddec.GetBuffer(0), ";");
    			while (pWord !=NULL){
    				//Comparer avec l'identifiant pour le premier
    				string basicstring(pWord);
    				if (ident == pWord){
    				//Si c'est bon, on vérifie le mot de passe
    					int i = 1;
    					pWord = strtok(NULL, ";");
    					if (passwd == pWord){
    						i = 2;
    						char *end;
    						pWord = strtok(NULL,";");
    						compte.droit=pWord;
    						truc = 1;
    						return TRUE;
    					}
    				}
    				//Sinon, ligne suivante
    				break;
    			}
    			CligneTemp.ReleaseBuffer();
    		}
    		truc = 2;
    		return FALSE; //On a parcouru tout le fichier sans trouver le bon
        }
    	truc = 3; //Ouverture du fichier ratée
    	return FALSE;
    }
    Je précise que, grâce à des breakpoints, j'ai pu voir que dans tous les cas (truc = 1,2 ou 3 c'est à dire si on a raté l'ouverture du fichier, si on a pas trouvé le bon couple ou dès qu'on a trouvé le bon identifiant) ca plante en sortie, puisque des breakpoints avant montrent que les variables sont bonnes.

    C'est au moment du "return TRUE" ou "return FALSE" que ca plante.

    Merci pour vos réponses.

  2. #2
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    a mon avis c'est ton utilisation de passwddec.GetBuffer(0) qui cause probleme sur la ligne OCrypt.DecryptString
    tu travailles avec le pointeur interne de la CString vide sans preciser de taille,
    et je suppose que DecryptString remplie le buffer ....

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    OCrypt.DecryptString((TCHAR *)ligne.c_str()
    Un joli const_cast, très mauvais.
    Utilise une CString et sa méthode GetBuffer().

    L'erreur de corruption a généralement lieu lors d'une désallocation (d'où l'erreur lors des appels implicites aux destructeurs) suite à un dépassement de buffer.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre éclairé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Par défaut
    Merci à vous deux, toujours aussi actifs

    Médinoc : En fait, je suis passé par une string pour ligne parce que je ne voyais pas comment faire pour une sorte de getline() avec un CString.

    Farscape : En effet, DecryptString remplit le buffer avec la chaîne décryptée. Mais il me semblait que qu'un des avantages des string (ou CString) par rapport aux char* était justement qu'on avait pas à se soucier de la taille ...

  5. #5
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    Citation Envoyé par jacklafrip
    Merci à vous deux, toujours aussi actifs

    Farscape : En effet, DecryptString remplit le buffer avec la chaîne décryptée. Mais il me semblait que qu'un des avantages des string (ou CString) par rapport aux char* était justement qu'on avait pas à se soucier de la taille ...
    Relis la définition de getbuffer , il y a réallocation mémoire sur la demande si la chaîne en cours est plus petite que celle demandée .
    toi tu mets 0 sur une chaîne vide ...
    comment veux tu que la CString sache à l'avance de quoi tu vas avoir besoin ?

    ta remarque est vraie quand on passe par les methodes de la classe ,mais la tu attaques le buffer interne en directe...

  6. #6
    Membre éclairé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Par défaut
    Suite à vos messages, j'ai changé mon code... et ca va mieux Mais il reste toujours un problème
    Maintenant, quand je rentre les bons identifiant et mot de passe, ca marche, ce qui est un très net progrès.
    Par contre, ca plante toujours si le mot de passe ou si l'identifiant est faux, c'est à dire si ma fonction renvoie "FALSE"

    Voici donc le code en question, dans lequel j'ai fait attention à la taille des objets, il me semble...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    bool CDlgIdentification::Verification(CString ident, CString passwd){
    	//Faire la vérification de l'identifiant et du mot de passe
    	std::ifstream fichier( "C:\\Temp\\passe.bin");
    	int truc;
        if ( fichier ) // ce test échoue si le fichier n'est pas ouvert
        {
    		//CString ligne;
            std::string ligne; // variable contenant chaque ligne lue
    		while ( std::getline( fichier, ligne ) ){
    			CCryptString OCrypt;
    			CString passwddec;
    			passwddec.GetBufferSetLength(ligne.length());
    			OCrypt.DecryptString((TCHAR*)ligne.c_str(), passwddec.GetBuffer(),cryptkey); //décrypter la ligne lue
    			CString Cligne = ligne.c_str();//copier le string en CString
    			CString CligneTemp = Cligne;
    			char* pWord= (char*)(malloc((sizeof(char*)*(passwddec.GetLength()))+1));
    			pWord = strtok(passwddec.GetBuffer(), ";");
    			while (pWord !=NULL){
    				//Comparer avec l'identifiant pour le premier
    				string basicstring(pWord);
    				if (ident == pWord){
    				//Si c'est bon, on vérifie le mot de passe
    					int i = 1;
    					pWord = strtok(NULL, ";");
    					if (passwd == pWord){
    						i = 2;
    						pWord = strtok(NULL,";");
    						compte.droit=pWord;
    						truc = 1;
    						return TRUE;
    					}
    				}
    				//Sinon, ligne suivante
    				break;
    			}
    			CligneTemp.ReleaseBuffer();
    		}
    		truc = 2;
    		ligne.~basic_string();
    		return FALSE; //On a parcouru tout le fichier sans trouver le bon
        }
    	truc = 3; //Ouverture du fichier ratée
    	return FALSE;
    }
    Cher Médinoc, je sais que la partie str::string ligne n'est pas belle, mais si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    while ( std::getline( fichier, ligne.GetBuffer() ) ){}
    ca me sort des erreurs de ifstream et char* ...
    Je vois pas trop comment faire sinon...

  7. #7
    Membre éclairé
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2006
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2006
    Messages : 245
    Par défaut
    PS : l'erreur est dans .../mfc/dlgcore.cpp, ce qui ne m'apprend pas grand chose... un tel niveau de programmation me paraissant inaténiable ... ou dans longtemps !!

  8. #8
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    autre remarque :
    attention aussi à l'utilisation de strtok tu ne testes pas le retour qui peut etre null.

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Mais La fonction ne demande pas une CString, elle demande un buffer.
    Et le buffer lui-même ne peut pas être modifié par la fonction...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. NTLDR is corrupt. The system cannot boot.
    Par Gabrielly dans le forum Windows Serveur
    Réponses: 1
    Dernier message: 24/01/2009, 15h10
  2. Heap Corruption Detected à la fermeture du programme
    Par Myth_Titans dans le forum Ogre
    Réponses: 7
    Dernier message: 16/06/2008, 20h20
  3. HEAP CORRUPTION DETECTED
    Par li_causi dans le forum C++
    Réponses: 4
    Dernier message: 27/04/2008, 22h44
  4. [Bug] Heap Corruption
    Par poukill dans le forum C++
    Réponses: 1
    Dernier message: 23/08/2007, 14h56
  5. Stack around the variable was corrupted
    Par tsp dans le forum C++
    Réponses: 8
    Dernier message: 05/04/2006, 16h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo