V2662. MISRA. Any value passed to a function from <ctype.h> should be representable as an unsigned character or be the value EOF.
This diagnostic rule is based on the MISRA (Motor Industry Software Reliability Association) software development guidelines.
This diagnostic rule is relevant only for C.
The functions from the <ctype.h>
standard library header accept int
arguments, but the passed value should be within the unsigned char
range or equal to the EOF
constant. If the value is passed outside this range, it results in undefined behavior (C11, Section 7.4).
Each function from <ctype.h>
uses the passed argument as an index to access the set of characters. If the passed value lies outside the unsigned char
range and is not equal to EOF
, an out-of-bounds access occurs. This leads to reading outside the array, which, in turn, leads to undefined behavior.
The example:
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;
}
The function generates a string of the specified length that contains randomly generated content with letters and numbers. However, due to an incorrect condition in the do
loop, the 256
value may be passed to the isalnum
function, which is outside the unsigned char
range ([0 .. 255]
).
The fixed code:
....
do
{
c = generate_random_value();
}
while (c < 0 || c > 255 || !isalnum(c));
....