Last Update 2021/07/27
-Wformat-truncation(Wformat-truncation=)
出力の切り捨てが発生する可能性が高いフォーマット文字列を伴う関数呼び出しに関する警告を出力
(snprintf、vsnprintfなど)
(snprintf、vsnprintfなど)
テスト概要
-Wformat-truncation、-Wformat-truncation=1、=2をそれぞれ指定した場合の出力を比較
実行環境
GCC-8.2.0
GNU C Library 2.28
GNU Binutils 2.31.1
GNU C Library 2.28
GNU Binutils 2.31.1
コード例・出力内容中の表記
・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
使用ファイル
sample.c
#include <stdio.h>
int main(void)
{
int n = 123456;
char c1[5];
char c2[11];
char c3[12];
/* 出力の切り捨てが発生する可能性が無い関数呼び出し */
snprintf(c1, 5, "test");
printf("%s\n", c1);
/* 出力の切り捨てが発生する関数呼び出し */
snprintf(c1, 5, "test\n");
printf("%s\n", c1);
/* 生成される文字列長が最小でも出力の切り捨てが発生する関数呼び出し */
snprintf(c1, 5, "test%i", n);
printf("%s\n", c1);
/* 変数の値次第では出力の切り捨ての可能性が有る関数呼び出し */
snprintf(c2, 11, "%i", n);
printf("%s\n", c2);
/* 生成される文字列長が最大でも出力の切り捨ての可能性の無い関数呼び出し */
snprintf(c3, 12, "%i", n);
printf("%s\n", c3);
return 0;
}
動作テスト
-Wformat-truncation、-Wformat-truncation=1、=2をそれぞれ指定した場合の出力を比較
オプション無しで実行
$ gcc sample.c 一切警告は出力されない
$ ./a.out
test
test <--- 出力の切り捨て発生
test <--- 出力の切り捨て発生
123456
123456
$
-Wformat-truncationオプションを指定して実行
$ gcc -Wformat-truncation sample.c
sample.c: In function ‘main’:
sample.c:15:25: warning: ‘snprintf’ output truncated before the last format character [-Wformat-truncation=]
snprintf(c1, 5, "test\n"); snprintfの出力が最後のフォーマット文字の前で切り捨てられる旨の警告
^
sample.c:15:2: note: ‘snprintf’ output 6 bytes into a destination of size 5
snprintf(c1, 5, "test\n"); 出力6バイトに対し格納先サイズは5バイト(確実に超過)
^~~~~~~~~~~~~~~~~~~~~~~~~
sample.c:19:25: warning: ‘snprintf’ output truncated before the last format character [-Wformat-truncation=]
snprintf(c1, 5, "test%i", n); snprintfの出力が最後のフォーマット文字の前で切り捨てられる旨の警告
^
sample.c:19:2: note: ‘snprintf’ output between 6 and 16 bytes into a destination of size 5
snprintf(c1, 5, "test%i", n); 出力6〜16バイトに対し格納先サイズは5バイト(確実に超過)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ 生成された実行ファイルの実行結果はオプション無しと同一の内容
-Wformat-truncation=1オプションを指定して実行
$ gcc -Wformat-truncation=1 sample.c
sample.c: In function ‘main’:
sample.c:15:25: warning: ‘snprintf’ output truncated before the last format character [-Wformat-truncation=]
snprintf(c1, 5, "test\n");
^
sample.c:15:2: note: ‘snprintf’ output 6 bytes into a destination of size 5
snprintf(c1, 5, "test\n");
^~~~~~~~~~~~~~~~~~~~~~~~~
sample.c:19:25: warning: ‘snprintf’ output truncated before the last format character [-Wformat-truncation=]
snprintf(c1, 5, "test%i", n);
^
sample.c:19:2: note: ‘snprintf’ output between 6 and 16 bytes into a destination of size 5
snprintf(c1, 5, "test%i", n);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
$ 上記、-Wformat-truncationオプションと同一の出力内容
(生成された実行ファイルの実行結果はオプション無しと同一の内容)
-Wformat-truncation=2オプションを指定して実行
$ gcc -Wformat-truncation=2 sample.c
sample.c: In function ‘main’:
sample.c:15:25: warning: ‘snprintf’ output truncated before the last format character [-Wformat-truncation=]
snprintf(c1, 5, "test\n");
^
sample.c:15:2: note: ‘snprintf’ output 6 bytes into a destination of size 5
snprintf(c1, 5, "test\n");
^~~~~~~~~~~~~~~~~~~~~~~~~
sample.c:19:23: warning: ‘%i’ directive output may be truncated writing between 1 and 11 bytes into a region of size 1 [-Wformat-truncation]
snprintf(c1, 5, "test%i", n);
^~
sample.c:19:2: note: ‘snprintf’ output between 6 and 16 bytes into a destination of size 5
snprintf(c1, 5, "test%i", n);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
sample.c:23:22: warning: ‘snprintf’ output may be truncated before the last format character [-Wformat-truncation=]
snprintf(c2, 11, "%i", n); snprintfの出力が、最後のフォーマット文字の前で切り捨てられる可能性がある旨の警告
^
sample.c:23:2: note: ‘snprintf’ output between 2 and 12 bytes into a destination of size 11
snprintf(c2, 11, "%i", n); 出力2〜12バイトに対し格納先サイズは11バイト(超過の可能性有り)
^~~~~~~~~~~~~~~~~~~~~~~~~
$ -Wformat-truncation=1に加え、変数の値次第で出力の切り捨てが発生する可能性のある場合も警告を出力
(生成された実行ファイルの実行結果はオプション無しと同一の内容)