Ответ 1
При использовании printf строка формата лучше будет строковым литералом, а не переменной:
printf("%s", str_a);
Я пытаюсь изучить 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]
Может ли кто-нибудь помочь?
При использовании printf строка формата лучше будет строковым литералом, а не переменной:
printf("%s", str_a);
Просто чтобы добавить что-то к другим ответам, вам лучше сделать это, потому что (давно?) люди так давно писали 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 )
Предупреждение вызвано компилятором, требующим, чтобы первый аргумент printf
был строковым литералом. Он хочет, чтобы вы это написали:
printf("%s\n", str_a);
Это потому, что первым параметром printf
является строка формата. После этого передаются аргументы формата.
Примечание. Фактически вы можете использовать переменную как строку формата, но вы, вероятно, не должны этого делать. Поэтому компилятор выдает предупреждение, а не ошибку.
Ошибка происходит от 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);