Sécurité des programmes : printf() et associés ---------------------------------------------- Si pour une raison ou une autre vous voulez afficher (ou "imprimer" dans un fichier) quelque chose qui vient de l'extérieur de votre programme, il faut toujours garder à l'esprit que la chaine de caractere _pourrait_ contenir quelque chose de plus ou moins facheux, volontairement ou non. Par exemple: FILE * fichier; char * texte; ... blabla ... fprintf( fichier, texte ); peut se reveler catastrophique si le texte en question vient de l'exterieur et contient: %2000000000i car ca va tenter d'ecrire 2Go d'espaces, puis la valeur de l'entier suivant present sur la pile (une valeur aleatoire donc). En general, il vaut mieux donc faire: fprintf( fichier, "%s", texte ); car aucune sequence d'echapement ne sera traitee. Ou meme: fprint( fichier, "%.50s", texte ); qui limitera la taille du texte "affiche" a 50 caracteres. Tout cela est bien joli, mais on a parfois vraiment besoin d'utiliser les sequences d'echappements... meme avec un texte venant de l'exterieur. Et la, pas de miracle, il faut faire treeeees attention. Le premier danger vient de la taille totale du texte affiche. Le second danger vient du fait qu'en mettant un certain nombre de sequences d'echappement, on peut faire planter le programme car le fonction printf() va tenter de lire trop loin dans la pile. Le troisieme danger vient de la sequence d'échappement %n qui sert a stocker le nombre de caracteres imprimes jusqu'alors. Le premier danger est facilement aneanti, enfin, facilement, vite dit car non standard, par les fonctions nprintf() snprintf() etc. Elles s'utilisent exactement comme printf() et autres, sauf qu'on indique en plus le nombre maxi de caracteres a imprimer. printf( 10, "%200i", 10 ); n'imprimera que 10 espaces, et rien d'autre, alors que sinon, on aurait eu 198 espaces suivis du nombre 10. sprintf( buffer, 10, "%2000i", 10 ); Si votre buffer fait au moins 11 octets, vous n'aurez jamais de debordement. http:/domainename.com/software/xnprintf.html contient ces fonctions sous forme de fichier source C/C++ directement exploitable sur des compilateurs 16-32 et 64-bits. Le second danger est mis en evidence par: printf( "%i%i%i%i..etc...%i%i%i%i" ); Si on met "un certain nombre" de %i alors la fonction printf() va aller chercher "un certain nombre" d'entiers dans la pile et arrivera peut-etre en fin de pile, avec une superbe erreur de style "general protection fault" si on est en mode protege. Pour lutter contre ca, il faut se palucher la chaine a afficher afin de verifier qu'elle ne contienne pas plus de, disons, 20 sequences d'echappement. Ou alors il faut verifier qu'elle ait le meme nombre de sequences d'echappement que le nombre de parametres que vous mettez au bout. ... et il ne suffit pas de compter le nombre de caractere '%' car \% et %% sont fait pour afficher, justement, le caractere '%'. De meme, %t n'affichera que 't'. Enfin, plein de chose dans le meme genre. En general, il est plus prudent de faire en sorte que le texte "venant de l'exterieur" ne soit pas affiche tel-quel. Il vaut mieux utiliser un syntaxe a vous: "Nombre d'utilisateur %users" et votre routine d'affichage transformera %users en autre chose. Le dernier danger est lie a la sequence d'echappement "%n": int i; printf( "123%n456\n", i ); printf( "%i\n", i ); donne: 123456 3 car i contiendra la valeur 3. Mais si je fait: printf( "%n%n%n%n%n%n%n%n%n%n" ); alors ca va ecrire 10 entiers a zero sur la pile... alors que je n'ai pas empile les entiers en question. Le programme va planter des que la fonction en cours va se terminer (sauf chance, si on a pas mal de variables locales et qu'elles ne servent plus, enfin bon, peu importe). La non plus, pas de miracle, il faut se palucher la chaine de caractere avant de tenter de l'imprimer.