2016-05-14 48 views
-1

我正在將VS2003的MFC應用程序遷移到VS2010。數以千計的函數調用_tcsset,_tcscpy,_tcsupr等。遷移後建立,C4996警告來建議使用_s版本的這些函數。我被要求不使用_CRT_SECURE_NO_WARNINGS並通過更改這些調用並使用_s版本來刪除所有警告。有數千個電話,並且在許多情況下,TCHAR *來自外部作爲論點。我無法分辨目標緩衝區有多大。那麼,我最好的選擇是什麼? 例如使用_s版本的功能,如_tcsset,_tcscpy等從VS2003遷移到VS2010時

TCHAR* fnc(TCHAR* tsrc, TCHAR* tdest) 
{ 
    _tcsset(tsrc,0); 
    _tcscpy(tdest,tsrc); 
    return(tdest); 
} 

如果我需要將這些調用更改爲_tcscpy_s。我該怎麼辦?在這種情況下使用非_s版本不是更好嗎?

+2

修復電話。如果沒有提供長度限制,則從安全角度來看,代碼已經非常糟糕(您發佈的代碼將是體面的證據)。搜索和替換將在編譯時產生原始指針使用情況。你將不得不硬着頭皮修改這些調用,包括可能爲自己的函數提供模板(在這種情況下爲'fnc)來協助。底線:如果簽名支票的人說你的問題指示了什麼,那就得做(或者停止使用C字符串來停止使用C字符串函數;也有很多工作)。 – WhozCraig

+0

謝謝您的主席先生的回覆。但如果我將這些調用作爲_tcscpy保留在外部TCHAR *的情況下,會不會更好。因爲代碼在VS2003中運行良好。或者,如果調用:'_tcscpy_s(tdest,_tcslen(tsrc)+ 1,tsrc);'它會不會僅僅以微小的差距來完成這項工作。 – Vik

+1

「工作」在創作緩衝區溢出攻擊的人眼中。 – WhozCraig

回答

0

如果您被告知要更改所有功能以使用_s,則必須繼續操作。你的榜樣作用將不得不更改爲:

TCHAR* fnc(TCHAR* tsrc, size_t src_els, TCHAR* tdest, size_t dst_els) 
{ 
    _tcsset_s(tsrc, src_els, 0); 
    _tcscpy(tdest, dst_els, tsrc); 
    return(tdest); 
} 

...那麼你將不得不調用改變以匹配,並可能不得不長度傳遞到這些功能,泡沫,漂洗,重複。

替代方法是切換到std::tstring(其中tstring是適用於stringwstring的類型定義)。這將是一樣多的工作,但會導致一個更清潔的界面,難以引起緩衝區溢出英寸

作爲一個方面的問題,你還建立既寬又窄版本的代碼?如果沒有,我會藉此機會徹底撕掉TCHAR,並使用wchar_t

如果你不使用std::string/wstring,你應該使用SAL註解,所以該函數將被聲明爲:

TCHAR* fnc(
    __inout_ecount(src_els) TCHAR* tsrc, size_t src_els, 
    __out_ecount(dst_els) TCHAR* tdest, size_t dst_els) 

這樣的工具集可以(至少在一定程度上)檢查你正在傳遞正確的價值觀。

你可能也需要寫的那些重要的元素,你的函數模板版本:

template <size_t s, size_t d> 
TCHAR *fnc(TCHAR (&tsrc)[s], TCHAR (&tdest)[d]) 
{ 
    return fnc(tsrc, s, tdest, d); 
} 
相關問題