Как этот буфер может быть переполнен? - PullRequest
13 голосов
/ 09 мая 2019

Я заранее прошу прощения за бесполезное название этого вопроса, но, похоже, ничто не подходит лучше.

Идея здесь состоит в том, чтобы скопировать argv в другую переменную, по существу создавая ее копию. Итак, основная идея того, что делает функция, это использовать malloc(), чтобы запросить некоторое пространство для копии, а затем выполнить итерацию по argv, делая копии каждого элемента.

Это код, с которым я работаю, среда разработки сейчас Visual Studio 2019 (даже если это не строго компилятор C ...):

// Returns a copy of an array of strings (inteded for argv, but should work with any of them):
wchar_t** copyArgv(size_t argc, wchar_t* argv[]) {
    // Allocate space for the array of arguments:
    wchar_t** argsCopy = malloc(((argc + 1) * sizeof(wchar_t*)));
    if (!argsCopy)
        return NULL;
    // Copy each one of them:
    for (size_t i = 0; i < argc; i++) {
        argsCopy[i] = _wcsdup(argv[i]);
        if (!argsCopy[i]) {
            // Should also free any previous copied string I left that part out in the paste.
            free(argsCopy);
            return NULL;
        }
    }
    argsCopy[argc] = NULL;
    return argsCopy;
}

Я пробовал разные способы сделать копию argv, но каждый из них позволяет VS полагать, что может быть переполнение буфера, когда я делаю копию аргумента (строка: argsCopy[i] = _wcsdup(argv[i]);) или считываю недопустимым данные в следующей строке, означающие чтение за пределами зарезервированного пространства.

Все это заставляет меня поверить, что проблема заключается в (сейчас) единственном malloc() вызове зарезервировать пространство для массива аргументов.

Тем не менее, я бьюсь головой о стену, пытаясь понять, в чем проблема, я имею в виду, я думаю, что я требую достаточно места.

Я пробовал и другие компиляторы, последние стабильные версии Clang и GCC, похоже, не показывают такого предупреждения. Поэтому я решил спросить вас, бывалые программисты, можете ли вы определить проблему, или это какая-то ошибка компилятора (вряд ли, я уверен).

Для справки: точные предупреждения, которые выдает VS2019 (в 64-битной компиляции):

В назначении:

Переполнение буфера при записи в argsCopy: размер записи составляет ((argc + 1)) * sizeof (wchar_t *) 'байтов, но может быть записано 16 байтов.

Следующая строка, тест на NULL:

Чтение недопустимых данных из argsCopy: читаемый размер составляет '((argc + 1)) * sizeof (wchar_t *)' байтов, но могут быть прочитаны 16 байтов.

Ответы [ 2 ]

0 голосов
/ 31 мая 2019

1) Ниже описан один из способов репликации argv, но 2) Я не могу понять, почему вы хотите сделать копию argv? какие варианты использования / пользовательские проблемы это решает?

Как я уже упоминал в (1), вот один из способов, который заключается в копировании всего содержимого argv в ваш буфер. Это выглядит примерно так (PS: возможны ошибки компиляции, когда я печатаю в телефоне, когда я нахожусь в такси, поэтому у меня нет доступа к высококачественному компилятору C для перекрестной проверки)

int numArgc = argc
char** argvCopy;

for (i=0;i<argc,i++)
{

 argvCopy[i] = malloc(sizeof(char)*strlen(argv[i]));
 strcpy(argvCopy[i], argv[i]);

}

//please do not forget to Free this malloc'ed memory (a very common C programming error) //when you don't need it anymore 

скажите, пожалуйста, проблему, которую хотите решить

0 голосов
/ 10 мая 2019

Это предупреждения от статического анализатора.Например, он пытается распознать ситуации переполнения буфера.

Предупреждение

Важно отметить, что это предупреждения, а не сообщения об ошибках.Компилятор говорит, что может быть что-то потенциально неправильно .Статический анализ, как правило, сложная вещь.

Ложный положительный результат

Нет ситуации переполнения буфера, поэтому это ложный положительный результат.Я бы предположил, что это сообщение исчезнет в будущем обновлении.

Изменить код бит

Если мы изменим строку выделения памяти следующим образом:

wchar_t** argsCopy = (wchar_t**)calloc(argc + 1, sizeof(wchar_t*));

тогда больше не будет предупреждений от Visual Studio 2019.

Количество выделенных байтов остается прежним.Однако предупреждения исчезают.

Тест

Перед изменением список ошибок VS выглядит следующим образом:

before

После применения предложенных мной изменений исчезли предупреждения:

after

...