Fehler: Format-String ist kein String-Literal

Lesezeit: 3 Minuten

Benutzeravatar von ShanZhengYang
ShanZhengYang

Ich habe ein einfaches Programm in C geschrieben, das Speicher für einen String-Vektor zuweist und diesen dann ausgibt.

#include <stdio.h>
#include <string.h>

int main() {
    char str_a[20];

    strcpy(str_a, "Hello, world!\n");
    printf(str_a);
}

Compiler verwenden gccdies gibt einen Kompilierungsfehler:

char_array2.c:8:12: warning: format string is not a string literal
      (potentially insecure) [-Wformat-security]
    printf(str_a);

1 warning generated.

Ich verstehe nicht, warum ich eine Warnung bekomme. Kann es mir jemand erklären?

  • Die Nachricht sagt Ihnen genau, was los ist. Was verstehst du daran nicht?

    – Etienne de Martell

    2. September 2015 um 20:55 Uhr


  • “1 Warnung generiert.” != “ein Kompilierungsfehler”.

    – chux – Wiedereinsetzung von Monica

    2. September 2015 um 21:12 Uhr

  • Eine Warnung ist nicht dasselbe wie ein Fehler.

    – Barmar

    2. September 2015 um 21:17 Uhr

Benutzeravatar von ouah
ouah

Verwenden:

printf("%s", str_a);

um die Warnung loszuwerden, wenn -Wformat-security aktiviert.

Die Diagnose ist informativ, um sie zu vermeiden Format-String-Schwachstelle. Zum Beispiel:

strcpy(str_a, "%x%x%x%x");
printf(str_a);

wäre gleichbedeutend mit:

printf("%x%x%x%x");

dem die erforderlichen Argumente fehlen und von einem Angreifer verwendet werden können, um den Stack zu dumpen (vorausgesetzt str_a unter Benutzerkontrolle steht, was bei Ihrem Programm aber nicht der Fall ist gcc ist nicht schlau genug, um es herauszufinden).

chux – Stellt Monicas Benutzeravatar wieder her
Chux – Wiedereinsetzung von Monica

Betrachten Sie 3 printf() Aussagen. Was kann der Compiler erkennen, wenn ein Formatkonflikt vorliegt?

void foo(const char *str_a,int x) {
  printf("Hello %d\n", x);  // Compiler sees this is good
  printf("Hello %d\n");     // Compiler sees this is bad --> warning/error
  printf(str_a, x);         // Compiler cannot tell - thus the warning
}

Die anderen Antworten sind besser. Aber wenn alles andere fehlschlägt, können Sie den Compiler anweisen, den Fehler zu ignorieren.

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat"
printf(str_a);
#pragma clang diagnostic pop

Gottriegel

  • Eeek. Nein 🙂 Einige Warnungen sollten gelesen und darauf reagiert werden, nicht ignoriert werden, um schlampigen Code zuzulassen, und das Letzte, was Sie in C wollen, ist schlampiger Code …

    – Gwyneth Llewelyn

    18. August um 12:00 Uhr

Dies ist kein Fehler, sondern eine Warnung. Wenn Sie printf verwenden, um eine Zeichenfolge zu drucken, möchten Sie so etwas wie printf("%s", str_a). Immer wenn Sie eine Zeichenfolge in Anführungszeichen (” “) haben, handelt es sich um ein Zeichenfolgenliteral. Dies bedeutet die Warnung, wenn sie besagt, dass es sich nicht um ein Zeichenfolgenliteral handelt. Ich bin mir nicht ganz sicher, warum Sie ein Zeichenfolgenliteral benötigen, aber normalerweise ist es am besten, dem Compiler zu folgen. jemand anderes kann wahrscheinlich die Notwendigkeit eines String-Literals klären.

Benutzeravatar von dbush
dbusch

Wenn Sie so etwas tun würden:

#include <stdio.h>
#include <string.h>

int main() {
    char str_a[20];

    fgets(str_a, 20, stdin);
    printf(str_a);
}

Und der Benutzer trat ein A %s bad %n stringkann der Benutzer Ihr Programm zum Absturz bringen und vielleicht eine Shell starten.

Mit dieser Eingabe kann der Benutzer dies effektiv tun:

printf("A %s bad %n string");

Das %s Bezeichner bewirkt, dass die Funktion von einer ungültigen Adresse liest, während der %n Bezeichner bewirkt dies schreiben an eine ungültige Adresse.

Benutzeravatar von Jens
Jens

Die Warnung wird ausgegeben, weil gute Compiler die Formatbezeichner gerne vergleichen %d im Formatstring gegen die Typen (hier an int) nach dem Format. Dies funktioniert offensichtlich nur für String-Literale, die der Compiler auf Spezifizierer analysieren kann. Ein Pointer-to-char in einer Variablen macht diese Plausibilitätsprüfung von Typen zunichte.

Beachten Sie, dass nicht übereinstimmende Formatbezeichner (oder Argumenttypen) dazu führen undefiniertes Verhalten und führen oft dazu, dass Garbage-Werte konvertiert werden oder abstürzen. Denken Sie darüber nach, was passiert, wenn a %s ist einem ganzzahligen Wert zugeordnet.

1432890cookie-checkFehler: Format-String ist kein String-Literal

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy