Sdílet prostřednictvím


Přetížení zabezpečení šablony

Společnost Microsoft zastaralá mnoho funkcí knihovny C Runtime (CRT) ve prospěch verzí vylepšených zabezpečením. Jedná se například strcpy_s o bezpečnější náhradu za strcpy. Zastaralé funkce jsou běžnými zdroji chyb zabezpečení, protože nezabrání operacím, které můžou přepsat paměť. Kompilátor ve výchozím nastavení vytvoří upozornění na vyřazení, když použijete některou z těchto funkcí. CRT poskytuje přetížení šablon jazyka C++, které těmto funkcím pomáhají usnadnit přechod na bezpečnější varianty.

Tento fragment kódu například vygeneruje upozornění, protože strcpy je zastaralý:

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

Upozornění na vyřazení je tam, abyste řekli, že váš kód může být nebezpečný. Pokud jste ověřili, že váš kód nemůže přepsat paměť, máte několik možností. Můžete se rozhodnout ignorovat upozornění, můžete před příkazy include pro hlavičky CRT definovat symbol _CRT_SECURE_NO_WARNINGS , který potlačí upozornění, nebo můžete aktualizovat kód tak, aby používal strcpy_s:

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

Přetížení šablony poskytují více možností. Pokud definujete _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES na 1, povolí přetížení šablon standardních funkcí CRT, které volají bezpečnější varianty automaticky. Pokud _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES je 1, nejsou potřeba žádné změny kódu. Na pozadí se volání strcpy změní na volání strcpy_s s argumentem velikosti zadaným automaticky.

#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

// ...

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

Makro _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES nemá vliv na funkce, které berou počet, například strncpy. Chcete-li povolit přetížení šablony pro funkce počtu, definujte _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT na 1. Než to ale uděláte, ujistěte se, že kód předá počet znaků, ne velikost vyrovnávací paměti (běžnou chybu). Kód, který explicitně zapíše ukončovací znak null na konci vyrovnávací paměti po volání funkce, je zbytečné, pokud je volána zabezpečená varianta. Pokud potřebujete zkrátit chování, přečtěte si téma _TRUNCATE.

Poznámka:

_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT Makro vyžaduje, aby _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES bylo také definováno jako 1. Pokud _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT je definována jako 1 a _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES je definována jako 0, aplikace nebude provádět žádné přetížení šablony.

Když definujete _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES hodnotu 1, povolíte přetížení šablon zabezpečených variant (názvy končící na "_s"). Pokud je v tomto případě _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1, musí být v původním kódu provedena jedna malá změna:

#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1

// ...

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

Je třeba změnit pouze název funkce (přidáním "_s"); přetížení šablony se postará o poskytnutí argumentu velikosti.

Ve výchozím nastavení _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES jsou _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT definovány jako 0 (zakázáno) a _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES jsou definovány jako 1 (povoleno).

Přetížení šablony funguje pouze pro statická pole. Dynamicky přidělené vyrovnávací paměti vyžadují další změny zdrojového kódu. Revize výše uvedených příkladů:

#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");

A tento příklad:

#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");

Viz také

Funkce zabezpečení v CRT
Soubory C runtime (CRT) a standardní knihovny C++ (STL) .lib