Вызовите через несмоделированный указатель функции

Указатель функции, объявленный без его типа или количества параметров, вызывает неожиданное поведение

Описание

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

Риск

Аргументы, переданные функции без прототипа, не могут совпадать с номером и типом параметров функционального определения, которое может вызвать неопределенное поведение. Если параметры ограничиваются подмножеством своей области типа, аргументы из недоверяемых источников могут инициировать уязвимости в вызванной функции.

Фиксация

Прежде, чем вызвать функцию через указатель, обеспечьте прототипа функции.

Примеры

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

#include <stdio.h>
#include <limits.h>
#define SIZE2 2

typedef void (*func_ptr)();
extern int getchar_wrapper(void);
extern void restricted_int_sink(int i);
/* Integer value restricted to
range [-1, 255] */
extern void restricted_float_sink(double i);
/* Double value restricted to > 0.0 */

                                              

func_ptr generic_callback[SIZE2] =
{
    (func_ptr)restricted_int_sink,
    (func_ptr)restricted_float_sink
};

void func(void)
{
    int ic;
    ic = getchar_wrapper();             
    /* Wrong index used for generic_callback.
	Negative 'int' passed to restricted_float_sink. */
	(*generic_callback[1])(ic); 
}
        
      

В этом примере вызов через func_ptr передает ic в качестве аргумента, чтобы функционировать generic_callback[1]. Тип ic может иметь отрицательные величины, в то время как параметр generic_callback[1] ограничивается, чтобы пустить в ход значения, больше, чем 0.0. Как правило, компиляторы и инструменты статического анализа не могут выполнить тип, проверяющий, когда вы не обеспечиваете прототип указателя.

Исправление — обеспечивает прототип указателя на функцию

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

#include <stdio.h>
#include <limits.h>
#define SIZE2 2

typedef void (*func_ptr_proto)(int);
extern int getchar_wrapper(void);
extern void restricted_int_sink(int i);
/* Integer value restricted to
range [-1, 255] */
extern void restricted_float_sink(double i);
/* Double value restricted to > 0.0 */                                        

func_ptr_proto generic_callback[SIZE2] =
{
    (func_ptr_proto)restricted_int_sink,
    (func_ptr_proto)restricted_float_sink
};

void func(void)
{
    int ic;
    ic = getchar_wrapper();              
    /* ic passed to function through
properly prototyped pointer. */
	(*generic_callback[0])(ic);
} 

Информация о результате

Группа: Программирование
Язык: C
Значение по умолчанию: на
Синтаксис командной строки: UNPROTOTYPED_FUNC_CALL
Влияние: носитель

Введенный в R2017b