...
This noncompliant code example has a typo that results in an assignment rather than a comparison.
Code Block |
---|
|
while (ch = '\t' &&|| ch == ' ' &&|| ch == '\n') {
/* ... */
}
|
Many compilers will warn about this condition. This coding error would typically be eliminated by adherence to MSC00-C. Compile cleanly at high warning levels. Although this code compiles, it will cause unexpected behavior to an unsuspecting programmer. If the intent was to verify a string such as a password, user name, or group user ID, the code may produce significant vulnerabilities and require significant debugging.
When comparisons are made between a variable and a literal or const-qualified variable, placing the variable on the right of the comparison operation can prevent a spurious assignment.
In this code example, the literals are placed on the left-hand side of each comparison. If the programmer were to inadvertently use an assignment operator, the statement would assign ch
to '\t'
, which is invalid and produces a diagnostic message.
Code Block |
---|
|
while ('\t' = ch &&|| ' ' == ch &&|| '\n' == ch) {
/* ... */
} |
Due to the diagnostic, the typo will be easily spotted and fixed.
Code Block |
---|
|
while ('\t' == ch &&|| ' ' == ch &&|| '\n' == ch) {
/* ... */
} |
As a result, any mistaken use of the assignment operator that could otherwise create a vulnerability for operations such as string verification will result in a compiler diagnostic regardless of compiler, warning level, or implementation.
EXP45-C-EX1: Assignment can be used where the result of the assignment is itself an operand to a comparison expression or relational expression. In this compliant example, the expression x = y
is itself an operand to a comparison operation:
Code Block |
---|
|
if ((x = y) != 0) { /* ... */ } |
EXP45-C-EX2: Assignment can be used where the expression consists of a single primary expression. The following code is compliant because the expression x = y
is a single primary expression:
Code Block |
---|
|
if ((x = y)) { /* ... */ } |
The following controlling expression is noncompliant because &&
is not a comparison or relational operator and the entire expression is not primary:
Code Block |
---|
|
if ((v = w) && flag) { /* ... */ } |
When the assignment of v
to w
is not intended, the following controlling expression can be used to execute the conditional block when v
is equal to w
:
Code Block |
---|
|
if ((v == w) && flag) { /* ... */ }; |
When the assignment is intended, the following controlling expression can be used:
Code Block |
---|
|
if (((v = w) != 0) && flag) { /* ... */ }; |
EXP45-C-EX3: Assignment can be used in a function argument or array index. In this compliant solution, the expression x = y
is used in a function argument:
Code Block |
---|
|
if (foo(x = y)) { /* ... */ } |
...