Безопасные перегрузки шаблоновSecure Template Overloads

Корпорация Майкрософт объявила устаревшими многие функции библиотеки C времени выполнения (CRT), заменив их версиями с более высоким уровнем безопасности.Microsoft has deprecated many C Runtime library (CRT) functions in favor of security-enhanced versions. Например, strcpy_s является более безопасной заменой для strcpy.For example, strcpy_s is the more secure replacement for strcpy. Устаревшие функции — это распространенные источники ошибок безопасности, так как они не предотвращают операции, которые могут перезаписывать память.The deprecated functions are common sources of security bugs, because they don't 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've verified that your code can't overwrite memory, you have several choices. Вы можете просто игнорировать это предупреждение. Вы можете добавить символ _CRT_SECURE_NO_WARNINGS перед инструкциями include в заголовках CRT, чтобы подавить предупреждение. Также вы можете изменить код, заменив эту функцию на 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 doesn't 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", в исходном коде необходимо сделать одно небольшое изменение.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).

Эти перегрузки шаблонов работают только для статических массивов.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; 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; change it to
                         // strcpy_s(szBuf, 10, "test");

См. такжеSee also

Функции безопасности в CRTSecurity Features in the CRT
Возможности библиотеки CRTCRT Library Features