2012-02-15 10 views
10

Cppcheck ha rilevato un potenziale problema in un codice come questo:Come potrebbero leggere i numeri usando sscanf in crash?

float a, b, c; 
int count = sscanf(data, "%f,%f,%f", &a, &b, &c); 

Si dice che: "scanf senza limiti di larghezza campo può andare in crash con i dati enorme". Come è possibile? È un bug noto in alcune implementazioni di sscanf? Capisco che i numeri possano traboccare (numericamente), ma come potrebbe il crash del programma? È un falso positivo in cppcheck?

Ho trovato una domanda simile: scanf Cppcheck warning, ma la risposta non è completamente soddisfacente. La risposta menziona la sicurezza del tipo, ma non dovrebbe essere un problema qui.

+0

Prova invece sscanf_s. Come normale scanf, sscanf non è sicuro da overflow. – guitarflow

+2

@guitarflow: il problema è che non vedo dove potrebbe traboccare. –

+2

@guitarflow Oppure no. 'sscanf_s' non è portabile e non è nemmeno sicuro, nonostante ciò che il nome suggerisce e sostiene Microsoft. –

risposta

6

Sono uno sviluppatore di Cppcheck.

Sì, questo è uno strano incidente. Con "enormi dati" significa milioni di cifre.

Se si utilizza il flag --verbose, cppcheck in realtà scriverà un piccolo codice di esempio che di solito si arresta in modo anomalo sui computer Linux.

Ecco un esempio di codice che si blocca con un errore di segmentazione sul mio computer Ubuntu 11.10:

#include <stdio.h> 

#define HUGE_SIZE 100000000 

int main() 
{ 
    int i; 
    char *data = new char[HUGE_SIZE]; 
    for (int i = 0; i < HUGE_SIZE; ++i) 
     data[i] = '1'; 
    data[HUGE_SIZE-1] = 0; 
    sscanf(data, "%i", &i); 
    delete [] data; 
    return 0; 
} 

Per informazioni non ottengo un crash quando provo questo codice di esempio a Visual Studio.

Ho usato g ++ versione 4.6.1 per compilare.

+1

La domanda rimane. Perché si blocca? Non vedo alcuna ragione quando il codice per analizzare il numero potrebbe essere qualcosa del tipo: 'per ogni cifra nei dati: risultato * = 10; risultato = + digit'. Come potrebbe quell'incidente? Perché non è stato risolto? –

+0

Volevo innanzitutto rispondere "È un falso positivo in Cppcheck?". È un incidente strano quindi è facile pensarlo. Non posso rispondere perché tecnicamente si blocca. È stato un problema noto e diffuso per anni. Sono d'accordo che con il tuo codice non può crash in modo evidente, che non è come i dati vengono analizzati. –

+0

Sì, ho capito. Grazie almeno per una risposta parziale. Ti ho dato +1. –

1

OK, si consideri questo codice:

int main(int argc, char *argv[]) { 
    const char* data = "9999999999999999999999999.9999999999999999999999//i put alot more 9's there, this just to get the point through 
    float a; 
    int count = sscanf(data, "%f", &a); 
    printf("%f",a); 
} 

l'output di questo programma è "inf" - nessun crash. E ho messo una grande quantità di 9 lì. Quindi sospetto che Cppcheck stia semplicemente sbagliando su questo.

+0

Quali compilatori hai controllato? –

+0

compilato con solo g ++. perché, hai ottenuto un risultato diverso con un altro compilatore? – WeaselFox

+0

Non ancora, ma ritengo che la conclusione "CppCheck è semplicemente sbagliato" potrebbe essere un po 'prematuro quando si esegue il test su un solo compilatore. (Posso solo testare con VC++ 2005 dove sono seduto ora, mi dispiace.) –

4

L'errore di segmentazione sembra essere un bug in glibc.

Ho appena provato questo con un programma simile, che si blocca in Ubuntu 10.04, ma funziona in Ubuntu 12.04.

Come ha detto Daniel Marjamäki, il suo programma si blocca in 11.10, credo che il bug sia risolto in mezzo.

Problemi correlati