2010-04-29 61 views
21

MSVC的「安全」sprintf函數有一個模板版本'知道'目標緩衝區的大小。然而,這個代碼簡單地繪製567890以上的bytes結束後的堆棧...用`snprintf_s`僞造的安全感

char bytes[5]; 
_snprintf_s(bytes, _TRUNCATE, "%s", "1234567890"); 

任何想法,我做錯了,或者這是一個已知的bug?

(我在VS2005的工作 - 在2008年或2010年沒有測試)

+2

很好的發現,它似乎。 – 2010-04-29 15:07:31

+2

哎唷!這是一件令人尷尬的事情。 – bobince 2010-04-29 15:18:29

回答

21

它確實出現了a bug in Visual C++ 2005(我遇到了麻煩該鏈接; Google also has it cached)。

我能夠重現在Visual C++ 2005在Visual C++ 2008和2010年,該字符串被截斷正確的問題(bytes包含1234\0),並預期返回-1

+3

謝謝!這似乎是錯誤報告真的從MS Connect站點消失... – xtofl 2010-04-30 09:16:39

-6

例子是錯誤的。

的代碼應該是:

char bytes[5]; 
_snprintf_s(bytes, 5, _TRUNCATE, "%s", "1234567890"); 

對於錯誤的代碼,它可能是編譯器沒有給出任何警告,但它會是snprintf的弱檢查的錯誤。

+9

-1:這個問題,這是舊的和回答,是談論'_snprintf_s'的重載,需要一個'字符數組寫入。它不必取得大小,因爲它可以從模板參數中獲取大小。除了VC 2005中的情況,這已被打破。 – 2012-02-02 21:46:23

1

這個例子確實是正確的。隨着版本 -

Microsoft Visual Studio 2005 
Version 8.0.50727.867 (vsvista.050727-8600) 
... 
Visual C++ 77626-009-0000007-41722 

- 包括SP1,Vista的修復程序和幾個圖書館修補程序 - 上述功能

template <size_t size> 
int _snprintf_s(
    char (&buffer)[size], 
    size_t count, 
    const char *format [, 
     argument] ... 
); 

仍然是馬車。然而,什麼是真正令人着迷的是,只有的4層變種的功能,此功能

  • OK:int _snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, :::
  • 巴吉:template <size_t size> int _snprintf_s(char (&buffer)[size], size_t count, :::
  • OK:int _snwprintf_s(寬字符版本)
  • OK:template <size_t size> int _snwprintf_s (是的,寬字符版本是OK)

是越野車,也就是說,如果使用非模板te版本是可以的,如果使用寬字符版本,也可以。驚人。