...
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.
Compliant Solution (RHS Variable)
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.
Exceptions
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)) { /* ... */ } |
Risk Assessment
Errors of omission can result in unintended program flow.
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Clang |
| -Wparentheses | Can detect some instances of this rule, but does not detect all | ||||||
CodeSonar |
| LANG.STRUCT.CONDASSIG | Assignment in conditional | ||||||
|
| Could detect violations of this recommendation by identifying any assignment expression as the top-level expression in an | |||||||
| CC2.EXP18 | Fully implemented | |||||||
|
| Can detect violations of this recommendation when the | |||||||
| ASSIGCOND.GEN |
| |||||||
| 114 S, 132 S | Enhanced Enforcement | |||||||
Parasoft C/C++test | 9.5 | BD-PB-CC | |||||||
PRQA QA-C |
| 3314, 3326, 3344, 3416 | Partially implemented | ||||||
SonarQube C/C++ Plugin |
| AssignmentInSubExpression |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...