web-dev-qa-db-ja.com

c配列-警告:文字列リテラルではない形式

私は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]

誰でも助けてくれますか?

38
bigl

Printfを使用する場合、フォーマット文字列は変数ではなく文字列リテラルである方が適切です。

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

他の答えに何かを追加するために、あなたはこれを行う方が良いでしょう(長い?)前に人々はそのようなprintfを書いて、ハッカーはスタックから読み書きする方法を見つけました、もっと多くの here
たとえば、次のような簡単なプログラム:

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 )
18
BlackBear

この警告は、コンパイラがprintfの最初の引数を文字列リテラルにしたいために発生します。これを書いてほしい:

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

これは、printfの最初のパラメーターがフォーマット文字列であるためです。その後、フォーマット引数が渡されます。

注:実際には、変数をフォーマット文字列として使用できますが、おそらくそうすべきではありません。そのため、コンパイラーはエラーではなく警告を発行します。

5
Marlon

エラーはprintf(str_a);から発生しています。コードはprintf("%s",str_a);である必要があります。printfの詳細については、次のリンクを参照してください。 http://www.cprogramming.com/tutorial/printf-format-strings.html

2
Jeff Woodard

printf()は、フォーマットが動的に作成された文字列ではなく、文字列リテラルであると想定しています。修正するには、これを試してください:

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

またはputsを使用します

puts(str_a);
1

「フォーマット引数なし」という警告を読んでください-つまり、文字列に%がありません。

printf("%s", str_a);を試してください

1
Ed Heal