c array-warning: форматировать не строковый литерал

Я пытаюсь изучить C, и уже столкнулся с проблемой. Я предполагаю, что это тривиально, но мне нужно это знать. Я написал:

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

int main() 
{
    char str_a[20];

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

Как только я попытаюсь скомпилировать его с помощью: GCC-g-o char_array2 char_array2.c я получаю сообщение об ошибке:

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

может кто-нибудь помочь пожалуйста?

6 ответов


при использовании printf строка формата лучше быть строковым литералом, а не переменной:

printf("%s", str_a);

просто чтобы добавить что-то к другим ответам, вам лучше сделать это, потому что (долго?) некоторое время назад люди писали printf так, и хакеры нашли способ читать и писать в стек, больше здесь.
Например, такая простая программа:

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 )

можно использовать для изменения значения test_var с 0xffffff на что-то другое, например 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 )

предупреждение вызвано компилятором, который хочет получить первый аргумент printf быть строковым литералом. Он хочет, чтобы вы написали следующее:

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

Это потому, что первый параметр printf - строка формата. После этого передаются аргументы format.

Примечание: Вы можете фактически использовать переменную в качестве строки формата, но вы, вероятно, не должны этого делать. Вот почему компилятор выдает предупреждение, а не ошибка.


ошибка исходит от printf(str_a);. Ваш код должен быть printf("%s",str_a); взгляните на следующую ссылку для получения дополнительной информации о функции printf. http://www.cprogramming.com/tutorial/printf-format-strings.html


printf() ожидает, что формат будет строковым литералом, а не динамически созданной строкой. Чтобы исправить, попробуйте следующее:

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

или использовать puts

puts(str_a);

пожалуйста, прочитайте предупреждение "нет аргументов формата" - т. е. нет % в строке.

попробовать printf("%s", str_a);