web-dev-qa-db-fra.com

tableau c - avertissement: format pas un littéral de chaîne

J'essaie d'apprendre C et j'ai déjà rencontré un problème. Je suppose que c'est trivial mais j'ai besoin de le savoir. J'ai écrit:

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

int main() 
{
    char str_a[20];

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

Une fois que j'essaye de le compiler avec: gcc -g -o char_array2 char_array2.c je reçois une erreur disant:

char_array2.c: In function ‘main’:
char_array2.c:9:2: warning: format not a string literal and no format arguments [-Wformat-security]

Quelqu'un peut-il aider s'il vous plaît?

38
bigl

Lorsque vous utilisez printf, la chaîne de formatage vaut mieux être un littéral de chaîne et non une variable:

printf("%s", str_a);
63
MByD

Juste pour ajouter quelque chose à d'autres réponses, vous feriez mieux de le faire car il y a (longtemps?) Les gens ont écrit printf comme ça et les pirates ont trouvé un moyen de lire et d'écrire dans la pile, plus ici .
Par exemple, un programme simple comme celui-ci:

blackbear@blackbear-laptop:~$ cat format_vul.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char text[1024];
    static int test_var = -1;

    if(argc < 2) {
        printf("Use: %s <input>\n", argv[0]);
        exit(-1);
    }

    strcpy(text, argv[1]);

    printf("The correct way:\n");
    printf("%s", text);

    printf("\nThe wrong way:\n");
    printf(text);

    printf("\n[*]: test_var @ %8p = %d ( 0x%x )\n", &test_var, test_var, test_var);
}
blackbear@blackbear-laptop:~$ ./format_vul AAAA
The correct way:
AAAA
The wrong way:
AAAA
[*]: test_var @ 0x804a024 = -1 ( 0xffffffff )

Peut être utilisé pour changer la valeur de test_var de 0xffffff à autre chose, comme 0xaabbccdd:

blackbear@blackbear-laptop:~$ ./format_vul $(printf "\x24\xa0\x04\x08JUNK\x2
5\xa0\x04\x08JUNK\x26\xa0\x04\x08JUNK\x27\xa0\x04\x08").%8x.%8x.%8x.%8x.%8x.
%8x.%8x.%8x.%8x.%110x.%n%239x%n%239x%n%239x%n
The correct way:
$�JUNK%�JUNK&�JUNK'�.%8x.%8x.%8x.%8x.%8x.%8x.%8x.%8x.%8x.%110x.%n%239x%n%239
x%n%239x%n
The wrong way:
$�JUNK%�JUNK&�JUNK'�.bfffefec.  154d7c.  155d7c.  155d7c.      f0.      f0.b
ffff4a4.       4.       4.                                                  
                                                     174.                   


                                                50415243                    


                                               50415243                     


                                              50415243
[*]: test_var @ 0x804a024 = -1430532899 ( 0xaabbccdd )
18
BlackBear

L'avertissement est dû au fait que le compilateur souhaite que le premier argument de printf soit un littéral de chaîne. Il veut que vous écriviez ceci:

printf("%s\n", str_a);

En effet, le premier paramètre de printf est la chaîne de format. Les arguments de format sont ensuite passés après cela.

Remarque: Vous pouvez en fait utiliser une variable comme chaîne de format, mais vous ne devriez probablement pas le faire. C'est pourquoi le compilateur émet un avertissement et non une erreur.

5
Marlon

L'erreur provient de printf(str_a);. Votre code doit être printf("%s",str_a); jetez un œil au lien suivant pour plus d'informations sur printf. http://www.cprogramming.com/tutorial/printf-format-strings.html

2
Jeff Woodard

printf() s'attend à ce que son format soit un littéral de chaîne, pas une chaîne créée dynamiquement. Pour résoudre ce problème, essayez ceci:

printf("%s", str_a); // %s denotes a string

Ou utilisez puts

puts(str_a);
1

Veuillez lire l'avertissement `` pas d'arguments de format '' - c'est-à-dire pas de% dans la chaîne.

Essayez printf("%s", str_a);

1
Ed Heal