Как можно считывать числа с помощью sscanf crash?

Cppcheck обнаружил потенциальную проблему в коде, подобном этому:

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

В нем говорится, что: "scanf без ограничений ширины поля может сбой с огромными данными". Как это возможно? Это известная ошибка в некоторых реализациях sscanf? Я понимаю, что числа могут переполняться (численно), но как может сбой программы? Это ложный позитив в cppcheck?

Я нашел аналогичный вопрос: scanf Cppcheck warning, но ответ не полностью удовлетворяет. В ответе упоминается безопасность типов, но это не должно быть проблемой.

Ответ 1

Я разработчик Cppcheck.

Да, это странный крах. С "огромными данными" это означает миллионы цифр.

Если вы используете флаг --verbose, тогда cppcheck на самом деле напишет небольшой примерный код, который обычно сбой на компьютерах linux.

Вот пример кода, который сбой сегментации на моем компьютере 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;
}

Для вашей информации я не получаю сбои, когда я пробую этот примерный код на visual studio.

Я использовал g++ версию 4.6.1 для компиляции.

Ответ 2

Ошибка сегментации, похоже, является ошибкой в ​​glibc.

Я только что проверил это с помощью подобной программы, которая вылетает в ubuntu 10.04, но работает в ubuntu 12.04.

Как сказал Даниэль Марьямяки, его программа вылетает в 11.10, я считаю, что ошибка между ними.

Ответ 3

ОК, рассмотрите этот код:

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

вывод этой программы - "inf" - без сбоев. И я поставил там огромное количество 9. Поэтому я подозреваю, что Cppcheck просто ошибается.