yohhoyの日記

技術的メモをしていきたい日記

printfファミリ書式指定%nの応用例

printf関数ファミリの滅多に使われない書式指定%nを利用したコードの例。本記事の内容はStack Overflowで見つけた質問と回答に基づく。

2021-10-11追記:C2x(C23)に向け N2834 にて%nの非推奨化(deprecate)が提案されている。

int n;
printf("%s: %nFoo\n", "hello", &n);
printf("%*sBar\n", n, "");

出力:

hello: Foo
       Bar

VisualC++の注意

MSVCでは既定で%nサポートが無効化されている。有効化するには _set_printf_count_output関数 を用いる必要がある。

セキュリティに関するメモ
%n形式は主に安全でないため、既定で無効になります。%nは書式指定文字列が検出された場合、無効なパラメーター ハンドラーが パラメーターの検証"に説明されているように、呼び出されます。%nサポートを有効にするには、_set_printf_count_outputを参照してください。

https://msdn.microsoft.com/ja-jp/library/hf4y5e3w.aspx

メモ:本質的には外部入力を書式指定文字列に与えることが脆弱性につながるため、%nだけを特別扱いするのも微妙な印象はある。とはいえ、脅威度の高い任意メモリ位置書き換えのリスクがある割に、無くても困らないマイナー機能であることは確か。

関連URL: