All char and short integer types are promoted to int or unsigned int before they are used in expressions. Consequently they receive high-order bits. These bits are either zero-extended for unsigned chars and shorts, or are sign-extended for signed chars and shorts. Consequently, arithmetic operations performed on ints yield the same values as on chars and shorts (at least in the low-order bits). However, bitwise operations may yield surprising effects.
Noncompliant Code Example
This example demonstrates how promotion to int
yields surprising effects.
uint8_t port = 0x5aU; uint8_t result_8 = ( ~port ) >> 4;
In this example, port
is negated, and shifted 4 bits to the right. If these operations were performed on a 8-bit integer, then result_8
would have the value 0x0aU
. However, port
will first be promoted to a 32-bit integer (signed or unsigned, depending on implementation), with the following results:
|
|
|
|
|
|
|
|
Compliant Solution
In this compliant solution, we truncate the negation back down to 8 bits. Consequently result_8
receives the expected value of 0x0aU
.
uint8_t port = 0x5aU; uint8_t result_8 = (static_cast<uint8_t> (~port)) >> 4;
Risk Assessment
Bitwise operations on shorts and chars can produce incorrect data.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
EXP14-C |
low |
likely |
high |
P9 |
L1 |
Automated Detection
Compass/ROSE can detect violations of this recommendation.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
This rule appears in the C++ Secure Coding Standard as EXP15-CPP. Beware of integer promotion when performing bitwise operations on chars or shorts.
References
[[MISRA 04]] Rule 10.5
EXP05-CPP. Do not use C-style casts 03. Expressions (EXP) EXP07-CPP. Do not diminish the benefits of constants by assuming their values in expressions