Faux sentiment de sécurité avec " snprintf s`
Les fonctions "secure" sprintf
de MSVC ont une version de modèle qui "connaît" la taille du tampon cible. Cependant, ce code peint heureusement 567890 sur la pile après la fin de bytes
...
char bytes[5];
_snprintf_s( bytes, _TRUNCATE, "%s", "1234567890" );
Une idée de ce que je fais de mal, ou est-ce un bug connu?
(je travaille dans VS2005 - n'a pas testé en 2008 ou 2010)
3 réponses
Il semble être un bug Dans Visual C++ 2005 (j'ai du mal à accéder à ce lien; Google l'a également mis en cache).
J'ai pu reproduire le problème dans Visual C++ 2005. Dans Visual C++ 2008 et 2010, la chaîne est correctement tronquée (bytes
contient 1234\0
) et -1
est renvoyé comme prévu.
L'exemple est en effet correct. À partir de la version --
Microsoft Visual Studio 2005
Version 8.0.50727.867 (vsvista.050727-8600)
...
Visual C++ 77626-009-0000007-41722
-- qui inclut SP1, le correctif vista et quelques correctifs de bibliothèque -- la fonction mentionnée ci-dessus
template <size_t size>
int _snprintf_s(
char (&buffer)[size],
size_t count,
const char *format [,
argument] ...
);
Toujours {[12] } est bogué. Cependant, ce qui est vraiment fascinant, c'est que seulement cette fonction de la variante 4 fonctions de
- OK:
int _snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, :::
- Buggy:
template <size_t size> int _snprintf_s(char (&buffer)[size], size_t count, :::
- OK:
int _snwprintf_s
(version à caractères larges) - OK:
template <size_t size> int _snwprintf_s
(oui, la version à caractères larges est OK)
Est buggé, c'est si l'on utilise la non-version du modèle c'est OK, et si l'on utilise soit du caractère large versions c'est OK aussi. Étonner.
L'exemple était faux.
Le code devrait être:
char bytes[5];
_snprintf_s( bytes, 5, _TRUNCATE, "%s", "1234567890" );
Pour le mauvais code, il peut y avoir un bug que le compilateur n'a pas donné d'avertissement mais ce serait la vérification faible pour snprintf.