2012-02-15 9 views
10

Cppcheck ha detectado un problema potencial en un código como el siguiente:¿Cómo se pueden bloquear los números con sscanf?

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

Se dice que: "scanf sin límites de anchura de campo puede chocar con enorme de datos". ¿Cómo es eso posible? ¿Es un error conocido en algunas implementaciones de sscanf? Entiendo que los números pueden desbordarse (numéricamente), pero ¿cómo podría colapsar el programa? ¿Es eso un falso positivo en cppcheck?

He encontrado una pregunta similar: scanf Cppcheck warning, pero la respuesta no es completamente satisfactoria. La respuesta menciona seguridad tipo, pero eso no debería ser un problema aquí.

+0

Pruebe sscanf_s en su lugar. Como scanf normal, sscanf no es desbordante seguro. – guitarflow

+2

@guitarflow: El problema es que no veo dónde puede desbordarse. –

+2

@guitarflow O no. 'sscanf_s' no es portátil y tampoco es realmente seguro, a pesar de lo que su nombre sugiere y afirma Microsoft. –

Respuesta

6

Soy un desarrollador de Cppcheck.

Sí, esta es una caída extraña. Con "datos enormes" significa millones de dígitos.

Si utiliza el indicador --verbose, entonces cppcheck escribirá un pequeño código de ejemplo que normalmente falla en las computadoras Linux.

Aquí es un ejemplo de código que se estrella con un fallo de segmentación en mi equipo 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; 
} 

Para su información no consigo un accidente cuando intento este ejemplo de código en Visual Studio.

Utilicé g ++ versión 4.6.1 para compilar.

+1

La pregunta permanece. ¿Por qué se cuelga? No veo ningún motivo cuando el código para analizar el número podría ser algo como: 'para cada dígito en datos: resultado * = 10; resultado + = dígito'. ¿Cómo podría chocar? ¿Por qué no está arreglado? –

+0

Principalmente quería responder "¿Es eso un falso positivo en Cppcheck?". Es un choque extraño, así que es fácil pensarlo. No puedo responder por qué técnicamente se bloquea. Ha sido un problema conocido y extendido durante años. Estoy de acuerdo con que con su código no se puede bloquear, así que obviamente no es así como se analizan los datos. –

+0

Sí, lo entiendo. Gracias al menos por una respuesta parcial. Te di +1. –

1

bien, considerar este código:

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); 
} 

la salida de este programa es "inf" - sin accidente. Y puse una gran cantidad de 9 allí. Entonces sospecho que Cppcheck está simplemente equivocado sobre esto.

+0

¿Con qué compiladores revisó esto? –

+0

compilado con solo g ++. ¿Por qué obtuviste un resultado diferente con otro compilador? – WeaselFox

+0

Todavía no, pero creo que la conclusión de que "CppCheck es simplemente incorrecto" puede ser un poco prematuro cuando se prueba en solo 1 compilador. (Solo puedo probar con VC++ 2005 donde estoy sentado ahora, lo siento). –

4

El error de segmentación parece ser un error en glibc.

Acabo de probar esto con un programa similar, que se cuelga en ubuntu 10.04, pero funciona en ubuntu 12.04.

Como dijo Daniel Marjamäki, su programa falla en 11.10, creo que el error es corregido en el medio.

Cuestiones relacionadas