CERT C: Rule MSC39-C

Не вызывайте va_arg () на va_list, который имеет неопределенное значение

Описание

Управляйте определением

Не вызывайте va_arg () на va_list, который имеет неопределенное значение. [1]

Реализация Polyspace

Это средство проверки проверяет на эти проблемы:

  • Недопустимый va_list аргумент.

  • Слишком много va_arg призывают к текущему списку аргументов.

Примеры

развернуть все

Проблема

Недопустимый va_list аргумент происходит, когда вы используете va_list переменная в качестве аргумента к функции в vprintf группа, но:

  • Вы не инициализируете переменную ранее с помощью va_start или va_copy.

  • Вы делаете недействительным переменную ранее с помощью va_end и не повторно инициализируйте его.

Например, вы вызываете функциональный vsprintf как vsprintf (buffer,format, args). Однако перед вызовом функции, вы не инициализируете va_list переменная args использование любого из следующего:

  • va_start(args, paramName)paramName последний параметр, передаваемый по имени функции аргумента переменной. Например, для функционального определения void func(int n, char c, ...) {}C последний параметр, передаваемый по имени.

  • va_copy(args, anotherList). anotherList другой допустимый va_list переменная.

Риск

Поведение неинициализированного va_list аргумент не определен. Вызывание функции с неинициализированным va_list аргумент может вызвать переполнения стека.

Фиксация

Перед использованием va_list переменная как аргумент функции, инициализируйте его va_start или va_copy.

Очистите переменную с помощью va_end только после всего использования переменной.

Пример - va_list Переменная, используемая после вызова va_end

#include <stdarg.h>
#include <stdio.h>

int call_vfprintf(int line, const char *format, ...) {
    va_list ap;
    int r=0;
    
    va_start(ap, format);
    r = vfprintf(stderr, format, ap);
    va_end(ap);

    r += vfprintf(stderr, format, ap);
    return r;
}

В этом примере, va_list переменная ap используется в vfprintf функция, после va_end макрос называется.

Коррекция — вызывает va_end После Используя va_list Переменная

Одна возможная коррекция должна вызвать va_end только после всего использования va_list переменная.

#include <stdarg.h>
#include <stdio.h>

int call_vfprintf(int line, const char *format, ...) {
    va_list ap;
    int r=0;
    
    va_start(ap, format);
    r = vfprintf(stderr, format, ap);
    r += vfprintf(stderr, format, ap);
    va_end(ap);
    
    return r;
}

Проблема

Слишком много призывов va_arg к текущему списку аргументов происходят когда количество вызовов va_arg превышает количество аргументов, переданных соответствующей функции variadic. Анализ повышает дефект только, когда функция variadic вызвана.

Слишком много призывов va_arg к текущему списку аргументов не повышают дефект когда:

  • Количество вызовов va_arg в variadic функция неопределенна. Например, если вызовы из внешнего источника.

  • va_list используемый в va_arg недопустимо.

Риск

Когда вы вызываете va_arg и существует никакой следующий аргумент, доступный в va_list, поведение не определено. Вызов va_arg может повредить данные или возвратить неожиданный результат.

Фиксация

Убедитесь, что вы передаете правильное количество аргументов к функции variadic.

Пример - никакой аргумент, доступный при вызове va_arg

#include <stdarg.h>
#include <stddef.h>
#include <math.h>

/* variadic function defined with
* one named argument 'count'
*/
int variadic_func(int count, ...) {
    int result = -1;
    va_list ap;
    va_start(ap, count);
    if (count > 0) {
        result = va_arg(ap, int);
        count --;
        if (count > 0) {
/* No further argument available 
* in va_list when calling va_arg
*/	

            result += va_arg(ap, int);
        }
    }
    va_end(ap);
    return result;
}

void func(void) {

    (void)variadic_func(2, 100); 

}

В этом примере параметр, передаваемый по имени и только один variadic аргумент передаются variadic_func() когда это называется в func(). На втором вызове va_arg, нет далее аргумент variadic доступен в ap и поведение не определено.

Коррекция — передача правильное количество аргументов к функции Variadic

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

#include <stdarg.h>
#include <stddef.h>
#include <math.h>

/* variadic function defined with
* one named argument 'count'
*/

int variadic_func(int count, ...) {
    int result = -1;
    va_list ap;
    va_start(ap, count);
    if (count > 0) {
        result = va_arg(ap, int);
        count --;
        if (count > 0) {

/* The correct number of arguments is
* passed to va_list when variadic_func()
* is called inside func()
*/			
            result += va_arg(ap, int); 
        }
    }
    va_end(ap);
    return result;
}

void func(void) {

    (void)variadic_func(2, 100, 200); 

} 

Проверяйте информацию

Группа: правило 48. Разное (MSC)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ-МЕЛЛОН И/ИЛИ ЕГО ИНСТИТУТА ПРОГРАММНОЙ ИНЖЕНЕРИИ СОДЕРЖАЛ, ЗДЕСЬ ПРЕДОСТАВЛЯЕТСЯ НА ОСНОВЕ "ASIS". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.