Est sscanf considéré comme sûr à utiliser?
J'ai de vagues souvenirs de suggestions qui sscanf
était mauvais. Je sais que ça ne sera pas de débordement de tampons si j'utilise le champ spécificateur de largeur, donc ma mémoire juste jouer des tours avec moi?
J'ai ajouté de la sécurité et de dépassement de capacité des balises en essayant de capturer l'attention des utilisateurs intéressés par ces sujets. J'espère que vous n'avez pas l'esprit.
Pas du tout. C'était un bon appel.
Pas du tout. C'était un bon appel.
OriginalL'auteur nmichaels | 2011-05-03
Vous devez vous connecter pour publier un commentaire.
Je pense que cela dépend de comment vous l'utilisez: Si vous numérisez à quelque chose comme
int
, c'est la fin. Si vous êtes à la recherche d'un string, ce n'est pas (sauf s'il y a une largeur de champ que j'oublie?).Modifier:
Il n'est pas toujours sans danger pour la numérisation des chaînes.
Si votre taille de la mémoire tampon est une constante, alors vous pouvez certainement spécifier que c'est quelque chose comme
%20s
. Mais si ce n'est pas une constante, vous devez le spécifier dans la chaîne de format, et vous devez faire:qui est possible, mais très facile de se tromper, comme je l'ai fait dans mon précédent edit (oublié de prendre soin de l'null-terminator). Vous pourriez même le dépassement de la chaîne de formatage de la mémoire tampon.
Essayez:
char buffer[2]; sscanf("Oops!", "%s", &buffer);
oui bien sûr..mais ici, vous n'êtes pas la spécification de la chaîne de largeur
si vous utilisez la bonne spécificateur de largeur pour votre tampon vous n'avez pas de risque de débordement de la chaîne. Par ailleurs, l'esperluette ne devrait pas être là.
Je pense que le problème est que vous pas toujours spécifier la chaîne de la largeur, car il n'est pas toujours une constante. Si c'est une variable, vous avez à construire la chaîne de format grâce à quelque chose comme
sprintf
, qui est une douleur que la plupart des gens ne veulent pas passer à travers.OriginalL'auteur Mehrdad
La raison pour laquelle
sscanf
pourrait être considérée comme mauvaise, c'est parce qu'il ne marche pas besoin de vous préciser maximale de la chaîne de largeur pour les arguments de la chaîne, ce qui pourrait entraîner des débordements si l'entrée de la lecture à partir de la source de la chaîne est plus longue. donc, la réponse exacte est: "c'est sûr, si vous spécifier des largeurs correctement dans la chaîne de format pas autrement.OriginalL'auteur z33m
Note, aussi longtemps que vos tampons sont au moins aussi longtemps que
strlen(input_string)+1
, il n'y a aucun moyen de l'%s
ou%[
prescripteurs peuvent déborder. Vous pouvez également utiliser la largeur de champ dans les spécificateurs si vous voulez imposer des limites plus strictes, ou vous pouvez utiliser%*s
et%*[
pour supprimer l'affectation et à la place, utiliser%n
avant et après pour obtenir le décalage de la chaîne d'origine, puis utilisez-les pour lire le sous-chaîne de la chaîne d'entrée.OriginalL'auteur R..
Oui c'est..si vous spécifiez la chaîne de la largeur de sorte que la sont pas de débordement de la mémoire tampon problèmes connexes.
De toute façon, comme @Mehrdad nous l'a montré, il y aura des problèmes possibles si la taille de la mémoire tampon n'est pas établie au moment de la compilation. Je suppose que mettre une limite à la longueur d'une chaîne de caractères qui peuvent être fournis à sscanf, pourrait éliminer le problème.
sscanf_s
dans Microsoft CRT?Je ne sais pas. De toute façon si vous êtes à la vérification de la taille de l'entrée, vous ne devriez pas avoir de problèmes de débordement de la mémoire tampon.
Selon eux, ils ont des versions plus sécurisées que les stnadard. Vérifier ici, premier membre de phrase.
mais sscanf n'accepte pas de chaîne largeur explicitement, sa doit être dans la chaîne de format. droit?
oui..dans la chaîne de format
OriginalL'auteur Heisenbug
Il y a 2 point de les prendre en charge.
La mémoire tampon de sortie de[s].
Comme mentionné par d'autres, si vous spécifiez une taille plus petite ou égale à la taille de la mémoire tampon de sortie dans la chaîne de format, vous êtes en sécurité.
La mémoire tampon d'entrée.
Ici, vous devez vous assurer qu'il est une valeur null mettre fin à chaîne ou que vous ne lirez plus que la taille de la mémoire tampon d'entrée.
Si la chaîne d'entrée n'est pas null
sscanf
peut lire au-delà des limites de la zone tampon et de crash si la memoire n'est pas attribué.OriginalL'auteur mathk
Tous les
scanf
fonctions fondamentales des défauts de conception, dont une partie seulement a pu être corrigé. Ils ne doivent pas être utilisés dans le code de production.Conversion numérique a plein de démons-fly-out-de-votre-nez comportement indéfini si une valeur dépasse la gamme représentable de la variable que vous voulez enregistrer la valeur. Je ne suis pas prise de cette place. La bibliothèque C est autorisé à le plantage de votre programme juste parce que quelqu'un a tapé trop d'entrée de chiffres. Même si il ne plante pas, il n'est pas obligé de faire quelque chose de sensé. Il n'y a pas de solution de contournement.
Comme l'a souligné dans plusieurs autres réponses,
%s
est tout aussi dangereux que l'infâmegets
. C'est possible pour éviter cela en utilisant le 'm' de modificateur, ou une largeur de champ, mais vous devez vous rappeler de le faire pour chaque champ de texte que vous souhaitez convertir, et vous devez câbler la largeur de champ dans la chaîne de format -- vous ne pouvez pas passersizeof(buff)
comme un argument.Si l'entrée ne correspond pas exactement à la chaîne de format,
sscanf
ne vous dit pas combien de caractères dans le tampon d'entrée il est arrivé avant qu'il a donné. Cela signifie en pratique la seule erreur de la politique de recouvrement est de supprimer la totalité de la mémoire tampon d'entrée. Cette peut être OK si vous êtes à la transformation d'un fichier linéaire simple tableau d'enregistrements de certaines de tri (par exemple, avec un fichier CSV, "ignorer le mal formé ligne et aller à la suivante" est un bon erreur de la politique de récupération), mais si l'entrée a plus de structure que ça, vous êtes arrosé.En C, l'analyse des emplois qui ne sont pas assez compliqué de justifier l'utilisation de
lex
etyacc
sont généralement mieux de le faire soit avec les expressions régulières POSIX (regex.h
) ou avec des roulés à la main chaîne de l'analyse. Lestrto*
numérique des fonctions de conversion ne avez bien spécifié et comportement utile sur le dépassement et ne vous dire comment peut personnages de l'entrée qu'ils ont consommé, etstring.h
a beaucoup de fonctions pratiques pour les roulés à la main analyseurs (strchr
,strcspn
,strsep
, etc).OriginalL'auteur zwol