2010-04-29 3 views
21

Le funzioni" sicure "di MSVC sprintf hanno una versione modello che" conosce "la dimensione del buffer di destinazione. Tuttavia, questo codice dipinge felicemente 567890 la risma dopo la fine della bytes ...Falso senso di sicurezza con `snprintf_s`

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

Qualche idea di cosa ho fatto di sbagliato, o si tratta di un bug noto?

(sto lavorando in VS2005 - non prova nel 2008 o 2010)

+2

Bella scoperta, sembrerebbe. –

+2

Ouch! È imbarazzante. – bobince

risposta

21

in quanto sembra essere a bug in Visual C++ 2005 (Sto avendo difficoltà a raggiungere quel collegamento; Google also has it cached).

sono stato in grado di riprodurre il problema in Visual C++ 2005. In Visual C++ 2008 e il 2010, la stringa viene troncata in modo corretto (bytes contiene 1234\0) e -1 viene restituito come previsto.

+3

Grazie! Sembra che il bug report sia davvero scomparso dal sito di MS Connect ... – xtofl

-6

L'esempio era sbagliato.

Il codice dovrebbe essere:

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

Per il codice errato, può un bug che il compilatore non ha dato alcun avvertimento, ma sarebbe il controllo debole snprintf.

+9

-1: la domanda, che è sia vecchia sia risposta, parla del sovraccarico di '_snprintf_s' che richiede un array di' char' per scrivere a . Non deve prendere la dimensione perché può ottenere la dimensione dal parametro template. Tranne che in VC 2005, questo era rotto. –

1

L'esempio è effettivamente corretto. A partire dalla versione -

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

- che include SP1, l'aggiornamento rapido Vista e alcuni degli aggiornamenti rapidi biblioteca - la funzione di cui sopra

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

ancora è buggy. Tuttavia, ciò che è veramente affascinante è che solo questa funzione delle 4 funzioni variante

  • 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 (versione carattere di larghezza)
  • OK: template <size_t size> int _snwprintf_s (sì, la versione wide character è OK)

è bacato, cioè se si sta utilizzando il non-templa la versione te è OK, e se si sta usando una delle versioni di caratteri wide va bene anche questo. Stupefacente.