2010-04-29 12 views
21

Funkcje" bezpieczne "MSVC sprintf mają wersję szablonu, która" zna "rozmiar bufora docelowego. Jednak ten kod szczęśliwie maluje 567890 nad stosu po zakończeniu bytes ...Fałszywe poczucie bezpieczeństwa dzięki `snprintf_s`

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

jakiś pomysł co robię źle, czy jest to znany błąd?

(Pracuję w VS2005 - nie testowałem w 2008 lub 2010)

+2

Ładne znalezisko, mogłoby się wydawać. –

+2

Ouch! To kłopotliwe. – bobince

Odpowiedz

21

To wydaje się być a bug in Visual C++ 2005 (mam problemy z dostaniem się do tego związku; Google also has it cached).

udało mi się odtworzyć problemu w Visual C++ 2005. W Visual C++ 2008 i 2010, łańcuch jest prawidłowo obcięty (bytes zawiera 1234\0) i -1 jest zwracany zgodnie z oczekiwaniami.

+3

Dzięki! Wygląda na to, że raport o błędzie rzeczywiście zniknął z witryny MS Connect ... – xtofl

-6

Przykład był nieprawidłowy.

Kod powinien być:

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

dla niewłaściwego kodu, może to błąd, że kompilator nie dała żadnego ostrzeżenia, ale byłoby słabe sprawdzanie dla snprintf.

+9

-1: Pytanie, które jest zarówno stare, jak i udzielone, mówi o przeciążeniu '_snprintf_s', które pobiera tablicę' char' do napisania do . Nie musi przyjmować rozmiaru, ponieważ może uzyskać rozmiar z parametru szablonu. Tyle że w VC 2005 było to zepsute. –

1

Przykład jest poprawny. Począwszy od wersji -

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

- który obejmuje SP1, Vista i poprawki kilka poprawek biblioteka - wyżej wymienionych funkcji

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

nadal jest wadliwy. Jednak to, co jest naprawdę fascynujące jest to, że tylko ta funkcja z 4 funkcjami wariantowych

  • OK: int _snprintf_s(char *buffer, size_t sizeOfBuffer, size_t count, :::
  • Buggy: template <size_t size> int _snprintf_s(char (&buffer)[size], size_t count, :::
  • OK: int _snwprintf_s (szeroki wersja znaków)
  • OK: template <size_t size> int _snwprintf_s (tak, wersja z szeroką literą jest w porządku)

jest buggy, czyli jeśli używa się nie-templa ta wersja jest w porządku, a jeśli używasz jednej z szerokich wersji znaków, to też jest OK. Niesamowity.