Ist sscanf als sicher zu verwenden?
Habe ich vage Erinnerungen an die Vorschläge, die sscanf
schlecht war. Ich weiß es nicht, überlauf-Puffer, wenn ich das Feld Breite Bezeichner, so ist meine Erinnerung nur spielen tricks mit mir?
InformationsquelleAutor der Frage nmichaels | 2011-05-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, es hängt davon ab, wie Sie Sie verwenden: Wenn Sie Scans für so etwas wie
int
es ist in Ordnung. Wenn Sie Scannen, für einen string, es ist nicht (es sei denn, es wurde eine Breite-Feld bin ich vergessen?).Bearbeiten:
Es ist nicht immer sicher für das Scannen von strings.
Wenn Ihr Puffer-Größe ist eine Konstante, dann können Sie sicher geben Sie es als so etwas wie
%20s
. Aber wenn es nicht eine Konstante ist, müssen Sie es im format-string, und Sie würde tun müssen:was möglich ist, aber sehr leicht zu bekommen, falsch, wie ich in meinem vorherigen edit (vergessen zu kümmern sich um die null-terminator). Man könnte sogar-overflow format-string-Puffer.
InformationsquelleAutor der Antwort Mehrdad
Der Grund, warum
sscanf
betrachtet werden könnte, schlecht ist, weil es nicht erfordern, dass Sie angeben, eine maximale string-Breite für string-Argumente, die dazu führen können, überläufe, wenn die Eingabe Lesen aus dem Quell-string länger ist. also die genaue Antwort ist: es ist sicher, wenn Sie angeben, breiten richtig in den format-string sonst nicht.InformationsquelleAutor der Antwort z33m
Beachten Sie, dass, solange Sie die Pufferspeicher sind mindestens so lang wie
strlen(input_string)+1
gibt es keine Möglichkeit, die%s
oder%[
Bezeichner kann überlaufen. Sie können auch verwenden, Feldbreite in den Planern, wenn Sie erzwingen möchten, strengere Grenzwerte, oder Sie können%*s
und%*[
zu unterdrücken Zuordnung und stattdessen%n
vor und nach, um die offsets in der original-string und verwenden dann die zu Lesen, die daraus resultierende sub-string aus dem input-string.InformationsquelleAutor der Antwort R..
Ja ist es..wenn Sie die Zeichenfolge anzugeben, die Breite, so das keine buffer-overflow-Probleme.
Sowieso, wie @Mehrdad hat uns gezeigt, gibt es mögliche Probleme, wenn die Größe des Puffers ist nicht gegründet worden, um zur compile-Zeit. Ich nehme an, dass eine Grenze für die Länge einer saite, die versorgt werden können sscanf, könnte das problem beheben.
InformationsquelleAutor der Antwort Heisenbug
Gibt es 2 Punkt zu kümmern.
Die Ausgabe-Puffer[s].
Wie erwähnt, von anderen, wenn Sie eine Größe angeben, die kleiner oder gleich der Größe des ausgabepuffers im format-string sind Sie sicher.
Eingabepuffer.
Hier müssen Sie sicherstellen, dass es eine null-terminate string oder dass Sie nicht Lesen mehr als die Eingangs-Puffer-Größe.
Wenn der input-string ist nicht null-terminiert
sscanf
Lesen Vergangenheit die Grenze des Puffers und Abstürzen, wenn die memorie ist nicht belegt.InformationsquelleAutor der Antwort mathk
Alle
scanf
Funktionen haben grundlegende design-Fehler, nur von denen einige behoben werden konnten. Sie sollte nicht in der Produktion verwendet werden code.Numerische Konvertierung in voller Dämonen-Fliegen-aus-dem-deine-Nase-nicht definiertes Verhalten, wenn ein Wert überläuft den darstellbaren Bereich der Variablen Sie speichern den Wert in. Ich bin nicht. Die C-Bibliothek darf Absturz Ihres Programms nur weil jemand getippt zu viele input-Ziffern. Auch wenn es nicht abstürzt, ist es nicht verpflichtet, alles zu tun sinnvoll. Es gibt keine Problemumgehung.
Wie schon in mehreren anderen Antworten
%s
ist genauso gefährlich wie die berüchtigtegets
. Es ist möglich um dies zu vermeiden, indem Sie entweder die 'm' - Modifikator oder ein Feld der Breite, aber Sie haben sich daran zu erinnern, das zu tun, für jeden einzelnen text-Feld, in das Sie konvertieren wollen, und Sie müssen Draht, der die Feldbreite in der format-string -- du kannst nicht vorbeisizeof(buff)
als argument.Wenn die Eingabe nicht genau dem format-string
sscanf
gar nicht sagen, wie viele Zeichen in den Eingabepuffer bekam es, bevor es Sie gab. Dies bedeutet, dass die einzige praktische Fehler-recovery-Politik ist zu verwerfen, der gesamte Eingabepuffer. Diese kann OK sein, wenn Sie die Bearbeitung einer Datei, die eine einfache lineare array von Datensätzen von einer Art (z.B. mit einer CSV-Datei, "überspringen Sie die fehlerhafte Zeile und gehen Sie zum nächsten" ist ein sinnvolles error recovery policy), aber wenn die Eingabe hat mehr Struktur als das, du bist abgespritzt.In C, analysieren Arbeitsplätze, die nicht kompliziert genug, um zu rechtfertigen, mit
lex
undyacc
sind in der Regel am besten entweder mit POSIX-regexps (regex.h
) oder mit von hand gerollt string-parsing. Diestrto*
numerischen Konvertierungsfunktionen tun haben gut angegeben und nützliches Verhalten auf überlauf und tun Ihnen sagen, wie können Zeichen der Eingabe, die Sie verbraucht, undstring.h
hat viele praktische Funktionen für die hand-gerollt-Parser (strchr
,strcspn
strsep
etc).InformationsquelleAutor der Antwort zwol