If an integer expression is compared to, or assigned to, a larger integer size, that integer expression should be evaluated in that larger size by explicitly casting one of the operands.
...
Noncompliant Code Example
This code example is non-compliant noncompliant on systems where size_t is an unsigned 32-bit value and long long is a 64-bit value. In this example, the programmer tests for integer overflow by comparing SIZE_MAX to length + BLOCK_HEADER_SIZE. Because length is declared as size_t, the addition is performed as a 32-bit operation and can result in an integer overflow. The comparison with SIZE_MAX in this example will always test false. If an overflow occurs, malloc() will allocate insufficient space for mBlock, which can lead to a subsequent buffer overflow.
...
GCC 3.4.4 produces a warning for this non-compliant noncompliant code example.
Compliant Solution
...
| Code Block | ||
|---|---|---|
| ||
enum { BLOCK_HEADER_SIZE = 16 };
void *AllocateBlock(size_t length) {
struct memBlock *mBlock;
if (SIZE_MAX - length < BLOCK_HEADER_SIZE) return NULL;
mBlock
= (struct memBlock *)malloc(length + BLOCK_HEADER_SIZE);
if (!mBlock) return NULL;
/* fill in block header and return data portion */
return mBlock;
}
|
...
Noncompliant Code Example
In this non-compliant noncompliant code example, the programmer attempts to prevent integer overflow by allocating an unsigned long long integer called alloc and assigning it the result from cBlocks * 16.
...
There are two separate problems with this non-compliant noncompliant code example. The first problem is that this code assumes an implementation where unsigned long long has a least four more bits than size_t. The second problem, assuming an implementation where size_t is a 32-bit value and unsigned long long is represented by a 64-bit value, is that to be compliant with C99, multiplying two 32-bit numbers in this context must yield a 32-bit result. Any integer overflow resulting from this multiplication will remain undetected by this code, and the expression alloc < UINT_MAX will always be true.
...