sprintf_s avec un tampon trop petit
Le code suivant provoque une erreur et tue ma demande. Il est logique que le tampon est à seulement 10 octets de long et le texte est de 22 octets de long (dépassement de tampon).
char buffer[10];
int length = sprintf_s( buffer, 10, "1234567890.1234567890." );
Comment puis-je rattraper cette erreur afin que je puisse le signaler, au lieu de planter ma demande?
Edit:
Après avoir lu les commentaires ci-dessous, je suis allé avec _snprintf_s. Si elle renvoie une valeur de -1 puis le tampon n'a pas été mis à jour.
length = _snprintf_s( buffer, 10, 9, "123456789" );
printf( "1) Length=%d\n", length ); //Length == 9
length = _snprintf_s( buffer, 10, 9, "1234567890.1234567890." );
printf( "2) Length=%d\n", length ); //Length == -1
length = _snprintf_s( buffer, 10, 10, "1234567890.1234567890." );
printf( "3) Length=%d\n", length ); //Crash, it needs room for the NULL char
source d'informationauteur Steven smethurst
Vous devez vous connecter pour publier un commentaire.
Au lieu de
sprintf_s
vous pouvez utilisersnprintf
(un.k.un_snprintf
sur windows).C'est par la conception. L'ensemble de point de
sprintf_s
et d'autres fonctions de la*_s
de la famille, est de prendre de dépassement de la mémoire tampon d'erreurs et de les traiter comme des condition violations. Cela signifie qu'ils ne sont pas vraiment destinés à être recouvrable. Il est conçu pour intercepter les erreurs uniquement, vous ne devriez jamais appelsprintf_s
si vous connaissez la chaîne peut être trop grand pour un tampon de destination. Dans ce cas, utilisezstrlen
d'abord pour vérifier et décider si vous avez besoin de couper.Cela fonctionne avec VC++ et est même plus sûr que d'utiliser snprintf (et certainement plus sûr que _snprintf):
La _TRUNCATE indicateur indique que la chaîne doit être tronqué. Sous cette forme, la taille de la mémoire tampon n'est pas passé, ce qui (paradoxalement!) est ce qui le rend si fort. Le compilateur utilise le modèle de la magie pour en déduire la taille de la mémoire tampon qui signifie qu'il ne peut pas être spécifié de manière incorrecte (surprenante de la commune d'erreur). Cette technique peut être appliquée pour créer d'autres en sécurité de la chaîne broché, tel que décrit dans mon billet de blog ici:
https://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/
À partir de MSDN:
L'autre principale différence entre sprintf_s et sprintf est que sprintf_s prend une longueur paramètre spécifie la taille de la mémoire tampon de sortie dans les personnages. Si le tampon est trop petit pour le texte en cours d'impression, puis le tampon est définie à une chaîne vide et le paramètre non valide gestionnaire est appelé. Contrairement à snprintf, sprintf_s garantit que le tampon va être nul (sauf si la taille de la mémoire tampon est de zéro).
Donc, idéalement ce que vous avez écrit doit fonctionner correctement.
Semble que vous avez écrit sur MSVC de la sorte?
Je pense que la MSDN docs pour sprintf_s dit qu'il affirmer meurt, donc je ne suis pas trop sûr si vous pouvez attraper par programme.
Comme LBushkin suggéré, vous êtes beaucoup mieux en utilisant des classes qui gèrent les cordes.
Voir section 6.6.1 de TR24731 qui est le C ISO Comité version de la fonctionnalité implémentée par Microsoft. Il offre des fonctions
set_constraint_handler()
abort_constraint_handler()
etignore_constraint_handler()
fonctions.Il y a des commentaires de Pavel Minaev ce qui suggère que la mise en œuvre de Microsoft n'adhère pas à la TR24731 proposition (qui est un "Type 2 Tech Rapport"), de sorte que vous ne pouvez pas être en mesure d'intervenir, ou vous pourriez avoir à faire quelque chose de différent de ce que les TR indique qui doit être fait. Pour cela, examiner MSDN.