MSVC の最新のセキュリティ更新プログラムに準拠するように「レガシー」コードを更新しようとしていますが、 から_vsnprintf
への移行で問題に直面してい_vsnprintf_s
ます。
具体的には_vsnprintf
、null バッファーとカウント/長さのゼロで呼び出し、結果を取得し、必要なサイズ ( ) のバッファーを割り当ててから、新しく割り当てられたバッファーと既知の正しいサイズで再度return value + 1
呼び出していました。_vsnprintf
size_t length = _vsntprintf(nullptr, 0, mask, params);
TCHAR *final = new TCHAR [length + 1];
_vsntprintf(final, length + 1, mask, params);
この動作は、MSDN で文書化されています。
count で指定されたバッファー サイズが、format と argptr で指定された出力を格納するには十分に大きくない場合、vsnprintf の戻り値は、count が十分に大きい場合に書き込まれる文字数になります。戻り値が count - 1 より大きい場合、出力は切り捨てられています。
で同じことをしようとしています_vsnprintf_s
が、そのドキュメントには同じが含まれていません。代わりに言う
データを格納するために必要なストレージと終端の null が sizeOfBuffer を超える場合、count が _TRUNCATE でない限り、パラメーターの検証で説明されているように、無効なパラメーター ハンドラーが呼び出されます。 1 が返されました。
とにかく次の方法で試してみてください:
size_t length = _vsntprintf_s(nullptr, 0, 0, mask, params);
これにより、「長さ」がゼロになります。_TRUNCATE
代わりに (-1) をカウントとして渡すと、次のアサーションは失敗します。
式: buffer != nullptr && buffer_count > 0
オーバーライド_set_invalid_parameter_handler
して、どうにかして長さを調べることは可能だと思いますが、もっと簡単な方法が必要ですか?