V2656. MISRA. Standard Library function 'memcmp' should not be used to compare null-terminated strings.
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 standard library function memcmp
should not be used to compare null-terminated strings.
Under this rule, null-terminated strings are:
- string literals
- arrays of the character essential type with a null terminator (
\0
).
The memcmp
function compares two memory blocks in a row byte by byte. When strings are compared, the actual length of each string (all characters up to the null terminator) may be shorter than the allocated buffer. As a result, the comparison of such buffers via the memcmp
function may lead to unexpected results. For example, two logically identical strings may be considered different because characters after the null terminator are compared too, even if they are not part of the string.
The example:
static _Bool FilesHaveSameContent(const FILE *lhs,
const FILE *rhs)
{
if (!lhs || !rhs) return false;
char l_buf[256];
char r_buf[256];
while (fgets(l_buf, sizeof(l_buf), lhs)
&& fgets(r_buf, sizeof(r_buf), rhs))
{
if (memcmp(l_buf, r_buf, sizeof(l_buf)) != 0) // <=
{
return false;
}
}
return feof(lhs) && feof(rhs);
}
The FilesHaveSameContent
function compares files string by string. File contents are read into l_buf
and r_buf
(each 256 bytes) using the fgets
function. Then, the memcmp
function compares buffers byte by byte.
The fgets
function reads the specified number of characters and stores them in the buffer until it reaches a newline character or the end of the file. If the read succeeded, the null terminator is written to the buffer after the last character read from the file.
As a result, if strings smaller than 255 bytes are read from two identical files, their comparison may produce an incorrect result, since the characters after the null terminator are not initialized.
To fix the issue, replace memcmp
with strcmp
or strncmp
:
if (strcmp(l_buf, r_buf) != 0)
{
return false;
}