2012-02-15 10 views
10

Cppcheck wykrył potencjalny problem w kodzie tak:W jaki sposób można odczytać liczby przy awarii sscanf?

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

Mówi ona, że: „scanf bez ograniczeń szerokości pole może upaść z ogromnym danych”. Jak to możliwe? Czy jest to znany błąd w niektórych implementacjach sscanf? Rozumiem, że liczby mogą się przepełnić (liczbowo), ale w jaki sposób program może się zawiesić? Czy to jest fałszywy pozytyw w cppcheck?

Znalazłem podobne pytanie: scanf Cppcheck warning, ale odpowiedź nie jest całkowicie satysfakcjonująca. W odpowiedzi wspomniano o bezpieczeństwie typu, ale nie powinno to stanowić problemu.

+0

Zamiast tego spróbuj sscanf_s. Jako normalny scanf, sscanf nie jest bezpieczny w przepełnieniu. – guitarflow

+2

@guitarflow: Problem polega na tym, że nie widzę miejsca, w którym może się on przepełnić. –

+2

@guitarflow Lub nie. 'sscanf_s' nie jest przenośny, a także nie jest faktycznie bezpieczny, pomimo tego, co sugeruje nazwa, a Microsoft twierdzi. –

Odpowiedz

6

Jestem programistą Cppcheck.

Tak, to dziwna awaria. Z "ogromnymi danymi" oznacza miliony cyfr.

Jeśli użyjesz opcji --verbose, to cppcheck zapisze trochę przykładowego kodu, który zwykle zawiesza się na komputerach z systemem Linux.

Oto przykładowy kod, który ulega awarii z winy segmentacji na moim Ubuntu 11.10 komputera:

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

Dla twojej informacji nie dostać awarię gdy próbuję ten przykładowy kod w visual studio.

Użyłem g ++ wersji 4.6.1 do kompilacji.

+1

Pytanie pozostaje. Dlaczego się zawiesza? Nie widzę żadnego powodu, dla którego kod do przeanalizowania liczby mógłby wyglądać tak: 'dla każdej cyfry w danych: wynik * = 10; wynik + = cyfra'. Jak to możliwe? Dlaczego nie jest naprawiony? –

+0

Przede wszystkim chciałem odpowiedzieć "Czy to fałszywy pozytyw w Cppcheck?". To dziwna awaria, więc łatwo jest tak myśleć. Nie mogę odpowiedzieć, dlaczego technicznie to się zawiesza. Jest to znany i powszechny problem od lat. Zgadzam się, że z twoim kodem nie może się tak łatwo zawiesić, że nie jest to sposób, w jaki dane są analizowane. –

+0

Tak, rozumiem. Dziękuję przynajmniej za częściową odpowiedź. Dałem ci +1. –

1

OK, należy rozważyć ten kod:

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

wyjście tego programu jest "inf" - bez awarii. I włożyłem tam ogromną ilość 9-ciu. Podejrzewam, że Cppcheck jest po prostu w błędzie.

+0

Z których kompilatorów to zrobiliście? –

+0

skompilowany za pomocą g ++. dlaczego otrzymałeś inny wynik z innym kompilatorem? – WeaselFox

+0

Jeszcze nie, ale uważam, że wniosek "CppCheck jest po prostu błędny" może być nieco przedwczesny podczas testowania tylko na jednym kompilatorze. (Mogę przetestować tylko z VC++ 2005, gdzie teraz siedzę, przepraszam.) –

4

Błąd segmentacji wydaje się być błędem w glibc.

Właśnie przetestowałem to z podobnym programem, który zawiesza się w Ubuntu 10.04, , ale działa w Ubuntu 12.04.

Jak powiedział Daniel Marjamäki, jego program ulega awarii w 11.10, uważam, że błąd jest naprawiony między .

Powiązane problemy