セキュリティ保護されたテンプレート オーバーロードSecure Template Overloads

Microsoft は、セキュリティが強化されたバージョンを優先するため、多くの C ランタイム ライブラリ (CRT) 関数を非推奨とされます。Microsoft has deprecated many C Runtime library (CRT) functions in favor of security-enhanced versions. たとえば、strcpy_sstrcpy の代わりになるセキュリティ強化版です。For example, strcpy_s is the more secure replacement for strcpy. 非推奨の関数は、メモリを上書きできる操作を禁止しないので、セキュリティ バグの一般的な原因になります。The deprecated functions are common sources of security bugs, because they do not prevent operations that can overwrite memory. 既定では、このような関数を使うと、コンパイラは非推奨の警告を生成します。By default, the compiler produces a deprecation warning when you use one of these functions. CRT では、セキュリティが強化されたバリアントに簡単に遷移するため、これらの関数の C++ テンプレート オーバーロードが用意されています。The CRT provides C++ template overloads for these functions to help ease the transition to the more secure variants.

たとえば、strcpy が非推奨とされているため、次のコード スニペットでは警告が発生します:For example, this code snippet generates a warning because strcpy is deprecated:

char szBuf[10];
strcpy(szBuf, "test"); // warning: deprecated

非推奨の警告は、コードが安全ではない可能性があることを伝えます。The deprecation warning is there to tell you that your code may be unsafe. コードがメモリを上書きできないことを確認した場合は、いくつかの選択肢があります。If you have verified that your code can't overwrite memory, you have several choices. 警告を無視する、CRT ヘッダーの include ステートメントの前でシンボル _CRT_SECURE_NO_WARNINGS を定義して警告を抑制する、または strcpy_s を使うようにコードを更新することができます。You can choose to ignore the warning, you can define the symbol _CRT_SECURE_NO_WARNINGS before the include statements for the CRT headers to suppress the warning, or you can update your code to use strcpy_s:

char szBuf[10];
strcpy_s(szBuf, 10, "test"); // security-enhanced _s function

テンプレート オーバーロードを使用することもできます。The template overloads provide additional choices. _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES を 1 に定義した場合、セキュリティが強化されたバリアントを自動的に呼び出す、標準 CRT 関数のテンプレート オーバーロードが有効になります。If you define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES to 1, this enables template overloads of standard CRT functions that call the more secure variants automatically. _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES が 1 の場合、コードを変更する必要はありません。If _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES is 1, then no changes to your code are necessary. 内部では、strcpy の呼び出しが strcpy_s の呼び出しに変換され、サイズ引数が自動的に指定されます。Behind the scenes, the call to strcpy is changed to a call to strcpy_s with the size argument supplied automatically.

#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

// ...

char szBuf[10];
strcpy(szBuf, "test"); // ==> strcpy_s(szBuf, 10, "test")

マクロ _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES は、strncpy などのカウントを確認する関数には影響しません。The macro _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES does not affect the functions that take a count, such as strncpy. カウント関数に対するテンプレート オーバーロードを有効にするには、_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT を 1 に定義します。To enable template overloads for the count functions, define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT to 1. ただし、定義する前に、コードがバッファー サイズ (よくある間違い) ではなく、文字数を渡しているかどうかを確認しておく必要があります。Before doing so, however, make sure that your code passes the count of characters, not the size of the buffer (a common mistake). また、セキュリティで保護されたバリアントを呼び出す場合、関数の呼び出し後、バッファーの最後に明示的に null 終端文字を書き込むコードも必要です。Also, code that explicitly writes a null terminator at the end of the buffer after the function call is unnecessary if the secure variant is called. 切り捨て動作が必要な場合は、「_TRUNCATE」を参照してください。If you need truncation behavior, see _TRUNCATE.

注意

マクロ _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT では、_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES も 1 と定義されている必要があります。The macro _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT requires that _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES is also defined as 1. _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT が 1 と定義されていて、_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES が 0 と定義されている場合、アプリケーションはテンプレート オーバーロードを実行しません。If _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT is defined as 1 and _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES is defined as 0, the application will not perform any template overloads.

_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES を 1 に定義すると、セキュリティで保護されたバリアント (名前の最後に "_s" が付いています) のテンプレート オーバーロードが有効になります。When you define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES to 1, it enables template overloads of the secure variants (names ending in "_s"). この場合、_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES が 1 であれば、元のコードに対して小さな変更が 1 つ必要になります。In this case, if _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES is 1, then one small change must be made to the original code:

#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1

// ...

char szBuf[10];
strcpy_s(szBuf, "test"); // ==> strcpy_s(szBuf, 10, "test")

関数名のみ変更する必要があります ("_s" を追加します)。サイズ引数については、テンプレート オーバーロードが処理します。Only the name of the function needs to be changed (by adding "_s"); the template overload takes care of providing the size argument.

既定では、_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES および _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT は 0 (無効) に定義され、_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES は 1 (有効) に定義されています。By default, _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES and _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT are defined as 0 (disabled) and _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES is defined as 1 (enabled).

これらのテンプレート オーバーロードは、静的な配列に対してのみ作用します。Note that these template overloads only work for static arrays. 動的に割り当てられるバッファーの場合、ソース コードにさらに変更が必要になります。Dynamically allocated buffers require additional source code changes. 上記の例をもう一度使用します。Revisiting the above examples:

#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

// ...

char *szBuf = (char*)malloc(10);
strcpy(szBuf, "test"); // still deprecated; you have to change it to
                       // strcpy_s(szBuf, 10, "test");

およびAnd this:

#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1

// ...

char *szBuf = (char*)malloc(10);
strcpy_s(szBuf, "test"); // doesn't compile; you have to change it to
                         // strcpy_s(szBuf, 10, "test");

関連項目See also

CRT のセキュリティ機能Security Features in the CRT
CRT ライブラリの機能CRT Library Features