維尼的蜂巢

RealTime??!! It’s amazing!!!!

warning C4996-VS2005遭受的問題 六月 12, 2008

Filed under: VC++/C++/C — kevinlin @ 12:16 上午

我的程式裡warning C4996大概有400多個,回想以前在VS2003時,一個warning都沒有,真是個美好的時代。
發生的warning像下面這樣
warning C4996: ‘sprintf’: This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS

這個錯誤是VS2005後,為了安全性而發生的錯誤,當然可以直接無視,不過大概是有三種方法
第一種就是直接無視他

#pragma warning(disable:4996)
或
#define _CRT_SECURE_NO_DEPRECATE 1

上面這個方法就可以很簡單的無視,不過注意要放在pre-compile header file “stdafx.h"最前面,要在還沒有include任何檔案之前。
第二種就是
直接使用Security CRT functions。(在後面會詳述)
第三種就是用
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
這個定義會自動幫你使用 Security CRT functions,但是warning一樣會出現,所以可以1、3混搭

方法一自然是不建議啊!!人家都說有security issure了,你還無視他的存在,那你當機是應該的。
VS2005為了讓我們建構更安全的應用程式,針對一些像是gets、sprintf、strcpy…等等C Run-time Library的操作,提供了比較安全一點的函式。大家稱他為Security Enhancements in the CRT

為什麼要這樣呢? 來看一個簡單的範例
MSDN上說C Run-time Library裡最不可靠的函式就是 gets,舉個例:

char buffer[10] = { 0 };
gets(buffer);

第一行宣告Buffer並將他初始化為0。(建議將所有變數初始化為明確的值,可以避免不必要的意外)。

接著gets會獨進一行你輸入的東西,這方法有甚麼問題呢??問題在,C-style陣列傳入到function中,是傳遞第一個element的指標。所以gets這個function會把char[]當成char*,因此他就沒有一個資訊來知道這個buffer大小了。

這都不是很重要,重要的來了,gets裡他假設這個buffer是無大小限制的(就是UINT_MAX),他只會把你輸入的東西丟進去buffer裡面,想做「緩衝區溢滿」攻擊的人就開始高興了。

所以,很多原始的C Run-time Library都有一樣的問題,缺乏一個驗證的數字,所以到了VS2005,它說「現在他們已經不適用了,該用我的好東西了。」

因為這些function是在以前效能主導的時代所寫的,我們現在已經是安全主導的年代了,這些老舊的東西微軟提供了一些新函式來取代,很簡單他在後面加了 _s ,例如 gets ==> gets_sstrcpy ==> strcpy_s

這樣上面的程式碼就變成了

char buffer[10] = { 0 };
gets_s(buffer,sizeof (buffer) / sizeof (buffer[0]));

上述的gets_s就是所謂的Security CRT functions(最後面我也把全部的function列表列出)

Security CRT functions的列表

Function Use
_access_s, _waccess_s Determine file-access permission
_malloca Allocates memory on the stack
asctime_s, _wasctime_s Convert time from type struct?tm to character string
bsearch_s Performs a binary search of a sorted array
_cgets_s, _cgetws_s Get a character string from the console
_chsize_s Changes the size of a file
clearerr_s Resets the error indicator for a stream
_controlfp_s Get and set the floating-point control word
_cprintf_s, _cprintf_s_l, _cwprintf_s, _cwprintf_s_l Formats and prints to the console
_cscanf_s, _cscanf_s_l, _cwscanf_s, _cwscanf_s_l Reads formatted data from the console
_ctime_s, _ctime32_s, _ctime64_s, _wctime_s, _wctime32_s, _wctime64_s Convert time from type time_t, __time32_t or __time64_t to character string
_ecvt_s Converts a double number to a string
_fcvt_s Converts a floating-point number to a string
fopen_s, _wfopen_s Open a file
fprintf_s, _fprintf_s_l, fwprintf_s, _fwprintf_s_l Print formatted data to a stream
freopen_s, _wfreopen_s Reassign a file pointer
fscanf_s, _fscanf_s_l, fwscanf_s, _fwscanf_s_l Read formatted data from a stream
_ftime_s, _ftime32_s, _ftime64_s Get the current time
_gcvt_s Converts a floating-point value to a string, which it stores in a buffer
getenv_s, _wgetenv_s Get a value from the current environment.
gets_s, _getws_s Get a line from the stdin stream
_gmtime32_s, _gmtime64_s Convert time from type time_t to struct tm or from type __time64_t to struct tm
_itoa_s, _i64toa_s, _ui64toa_s, _itow_s, _i64tow_s, _ui64tow_s Convert an integer to a string
_lfind_s Performs a linear search for the specified key
localtime_s, _localtime32_s, _localtime64_s Convert time from type time_t to struct tm or from type __time64_t to struct tm with local correction
_lsearch_s Performs a linear search for a value; adds to end of list if not found
_ltoa_s, _ltow_s Convert a long integer to a string
_makepath_s, _wmakepath_s Create a path name from components
_mbccpy_s, _mbccpy_s_l Copies a multibyte character from one string to another string
_mbsnbcat_s, _mbsnbcat_s_l Appends, at most, the first n bytes of one multibyte character string to another
_mbsnbcpy_s, _mbsnbcpy_s_l Copies n bytes of a string to a destination string
mbsrtowcs_s Converts a multibyte character string to a corresponding wide characters string
mbstowcs_s, _mbstowcs_s_l Converts a sequence of multibyte characters to a corresponding sequence of wide characters
memcpy_s, wmemcpy_s Copies characters between buffers
memmove_s, wmemmove_s Moves one buffer to another
_mktemp_s, _wmktemp_s Create a unique filename
printf_s, _printf_s_l, wprintf_s, _wprintf_s_l Print formatted output to the standard output stream
_putenv_s, _wputenv_s Create, modify, or remove environment variables
qsort_s Performs a quick sort
rand_s Generates a pseudorandom number
scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l Read formatted data from the standard input stream
_searchenv_s, _wsearchenv_s Search for a file using environment paths
_snprintf_s, _snprintf_s_l, _snwprintf_s, _snwprintf_s_l Write formatted data to a string
_snscanf_s, _snscanf_s_l, _snwscanf_s, _snwscanf_s_l Read formatted data of a specified length from a string.
_sopen_s, _wsopen_s Open a file for sharing
_splitpath_s, _wsplitpath_s Break a path name into components
sprintf_s, _sprintf_s_l, swprintf_s, _swprintf_s_l Write formatted data to a string
sscanf_s, _sscanf_s_l, swscanf_s, _swscanf_s_l Read formatted data from a string
strcat_s, wcscat_s, _mbscat_s Append a string
strcpy_s, wcscpy_s, _mbscpy_s Copy a string
_strdate_s, _wstrdate_s Return current system date as string
strerror_s, _strerror_s, _wcserror_s, __wcserror_s Get a system error message (strerror, _wcserror) or prints a user-supplied error message (_strerror, __wcserror)
_strlwr_s, _strlwr_s_l, _mbslwr_s, _mbslwr_s_l, _wcslwr_s, _wcslwr_s_l Convert a string to lowercase
strncat_s, _strncat_s_l, wcsncat_s, _wcsncat_s_l, _mbsncat_s, _mbsncat_s_l Append characters to a string
strncpy_s, _strncpy_s_l, wcsncpy_s, _wcsncpy_s_l, _mbsncpy_s, _mbsncpy_s_l Copy characters of one string to another
_strtime_s, _wstrtime_s Return current system time as string
strtok_s, _strtok_s_l, wcstok_s, _wcstok_s_l, _mbstok_s, _mbstok_s_l Find the next token in a string, using the current locale or a locale passed in
_strupr_s, _strupr_s_l, _mbsupr_s, _mbsupr_s_l, _wcsupr_s, _wcsupr_s_l Convert a string to uppercase
tmpfile_s Creates a temporary file
tmpnam_s, _wtmpnam_s Generate names you can use to create temporary files
_ultoa_s, _ultow_s Convert an unsigned long integer to a string
_umask_s Sets the default file-permission mask
_vcprintf_s, _vcprintf_s_l, _vcwprintf_s, _vcwprintf_s_l Write formatted output to the console using a pointer to a list of arguments
vfprintf_s, _vfprintf_s_l, vfwprintf_s, _vfwprintf_s_l Write formatted output using a pointer to a list of arguments
vprintf_s, _vprintf_s_l, vwprintf_s, _vwprintf_s_l Write formatted output using a pointer to a list of arguments
vsnprintf_s, _vsnprintf_s, _vsnprintf_s_l, _vsnwprintf_s, _vsnwprintf_s_l Write formatted output using a pointer to a list of arguments
vsprintf_s, _vsprintf_s_l, vswprintf_s, _vswprintf_s_l Write formatted output using a pointer to a list of arguments
wcrtomb_s Convert a wide character into its multibyte character representation
wcsrtombs_s Convert a wide character string to its multibyte character string representation
wcstombs_s, _wcstombs_s_l Converts a sequence of wide characters to a corresponding sequence of multibyte characters
wctomb_s, _wctomb_s_l Converts a wide character to the corresponding multibyte character

參考:
Security Enhancements in the CRT :
http://msdn2.microsoft.com/en-us/library/8ef0s5kh(VS.80).aspx
Secure Template Overloads :
http://msdn2.microsoft.com/en-us/library/ms175759(VS.80).aspx

題外話:

Another source of deprecation warnings, unrelated to security, is the POSIX functions. Replace POSIX function names with their standard equivalents (for example, change access to _access), or disable POSIX-related deprecation warnings by defining _CRT_NONSTDC_NO_WARNINGS. For more information, see Deprecated CRT Functions.

 

5 Responses to “warning C4996-VS2005遭受的問題”

  1. […] warning C4996-VS2005遭受的問題 ” 維尼的蜂巢 我的程式裡warning C4996大概有400多個,回想以前在VS2003時,一個warning都沒有,真是個美好的時代。 … _itoa_s, _i64toa_s, _ui64toa_s, _itow_s, _i64tow_s, _ui64tow_s. Convert an integer to a … […]

  2. […] warning C4996-VS2005遭受的問題 ” 維尼的蜂巢 我的程式裡warning C4996大概有400多個,回想以前在VS2003時,一個warning都沒有,真是個美好的時代。 發生的warning像下面這樣. warning … getenv_s, _wgetenv_s. Get a value from the current environment. gets_s, _getws_s. Get a … […]

  3. […] warning C4996-VS2005遭受的問題 ” 維尼的蜂巢 我的程式裡warning C4996大概有400多個,回想以前在VS2003時,一個warning都沒有,真是個美好的時代。 … _malloca. Allocates memory on the stack. asctime_s, _wasctime_s. Convert time from type … […]

  4. […] warning C4996-VS2005遭受的問題 ” 維尼的蜂巢 我的程式裡warning C4996大概有400多個,回想以前在VS2003時,一個warning都沒有,真是個美好的時代。 … _chsize_s. Changes the size of a file. clearerr_s. Resets the error indicator for a stream … […]

  5. […] warning C4996-VS2005遭受的問題 ” 維尼的蜂巢 我的程式裡warning C4996大概有400多個,回想以前在VS2003時,一個warning都沒有,真是個美好的時代。 發生的warning像下面這樣. warning … _splitpath_s, _wsplitpath_s. Break a path name into components … […]


發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s