V2662. MISRA. Any value passed to a function from <ctype.h> should be representable as an unsigned character or be the value EOF.
Диагностическое правило основано на руководстве 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));
....
Данная диагностика классифицируется как:
|