Как можно было читать числа с помощью sscanf? - PullRequest
11 голосов
/ 15 февраля 2012

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

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

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

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

Ответы [ 3 ]

7 голосов
/ 15 февраля 2012

Я разработчик 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.

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

4 голосов
/ 12 июня 2012

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

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

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

1 голос
/ 15 февраля 2012

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

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

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

...