Диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Правило актуально только для языка C.
Функции стандартной библиотеки из заголовочного файла <ctype.h> принимают аргумент типа int, однако передаваемое значение должно находиться в диапазоне unsigned char, либо быть равным константе EOF. Передача значения за пределами этого диапазона приводит к неопределённому поведению (C11, п. 7.4).
Каждая функция из <ctype.h> использует переданный аргумент в качестве индекса для доступа к таблице классификации символов. Если переданное значение не находится в диапазоне unsigned char и не равно EOF, то происходит обращение за пределы таблицы. Это приводит к чтению за границей массива, поведение программы, в таком случае, не определено.
Рассмотрим пример:
int generate_random_value();
char *generate_random_name(size_t len)
{
char *res = (char *) malloc(len * sizeof(char));
if (!res) return NULL;
for (size_t i = 0; i < len; ++i)
{
int c;
do
{
c = generate_random_value();
}
while (c < 0 || c > 256 || !isalnum(c));
res[i] = c;
}
return res;
}
Функция генерирует строку заданной длины с содержимым, сгенерированным случайно и состоящим из букв и цифр. Однако из-за некорректного условия цикла do в функцию isalnum возможно попадание значения 256, которое не входит в диапазон unsigned char ([0 .. 255]).
Исправленный пример:
....
do
{
c = generate_random_value();
}
while (c < 0 || c > 255 || !isalnum(c));
....
Данная диагностика классифицируется как:
|