Skip to content

Commit 419d25c

Browse files
authored
Merge pull request github#5325 from ihsinme/ihsinme-patch-245
CPP: Add query for CWE-783 Operator Precedence Logic Error When Use Bool Type
2 parents 981c5de + 3f215d0 commit 419d25c

File tree

6 files changed

+125
-0
lines changed

6 files changed

+125
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
if(len=funcReadData()==0) return 1; // BAD: variable `len` will not equal the value returned by function `funcReadData()`
2+
...
3+
if((len=funcReadData())==0) return 1; // GOOD: variable `len` equal the value returned by function `funcReadData()`
4+
...
5+
bool a=true;
6+
a++;// BAD: variable `a` does not change its meaning
7+
bool b;
8+
b=-a;// BAD: variable `b` equal `true`
9+
...
10+
a=false;// GOOD: variable `a` equal `false`
11+
b=!a;// GOOD: variable `b` equal `false`
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Finding places of confusing use of boolean type. For example, a unary minus does not work before a boolean type and an increment always gives true.</p>
7+
8+
9+
</overview>
10+
<recommendation>
11+
12+
<p>we recommend making the code simpler.</p>
13+
14+
</recommendation>
15+
<example>
16+
<p>The following example demonstrates erroneous and fixed methods for using a boolean data type.</p>
17+
<sample src="OperatorPrecedenceLogicErrorWhenUseBoolType.c" />
18+
19+
</example>
20+
<references>
21+
22+
<li>
23+
CERT C Coding Standard:
24+
<a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP00-C.+Use+parentheses+for+precedence+of+operation">EXP00-C. Use parentheses for precedence of operation</a>.
25+
</li>
26+
27+
</references>
28+
</qhelp>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* @name Operator Precedence Logic Error When Use Bool Type
3+
* @description --Finding places of confusing use of boolean type.
4+
* --For example, a unary minus does not work before a boolean type and an increment always gives true.
5+
* @kind problem
6+
* @id cpp/operator-precedence-logic-error-when-use-bool-type
7+
* @problem.severity warning
8+
* @precision medium
9+
* @tags correctness
10+
* security
11+
* external/cwe/cwe-783
12+
* external/cwe/cwe-480
13+
*/
14+
15+
import cpp
16+
import semmle.code.cpp.valuenumbering.HashCons
17+
18+
/** Holds if `exp` increments a boolean value. */
19+
predicate incrementBoolType(IncrementOperation exp) {
20+
exp.getOperand().getType() instanceof BoolType
21+
}
22+
23+
/** Holds if `exp` applies the unary minus operator to a boolean type. */
24+
predicate revertSignBoolType(UnaryMinusExpr exp) {
25+
exp.getAnOperand().getType() instanceof BoolType and
26+
exp.getFullyConverted().getType() instanceof BoolType
27+
}
28+
29+
/** Holds, if this is an expression, uses comparison and assignment outside of execution precedence. */
30+
predicate assignBoolType(Expr exp) {
31+
exists(ComparisonOperation co |
32+
exp.(AssignExpr).getRValue() = co and
33+
exp.isCondition() and
34+
not co.isParenthesised() and
35+
not exp.(AssignExpr).getLValue().getType() instanceof BoolType and
36+
not exists(Expr exbl |
37+
hashCons(exbl.(AssignExpr).getLValue()) = hashCons(exp.(AssignExpr).getLValue()) and
38+
not exbl.isCondition() and
39+
exbl.(AssignExpr).getRValue().getType() instanceof BoolType and
40+
exbl.(AssignExpr).getLValue().getType() = exp.(AssignExpr).getLValue().getType()
41+
) and
42+
co.getLeftOperand() instanceof FunctionCall and
43+
not co.getRightOperand().getType() instanceof BoolType and
44+
not co.getRightOperand().getValue() = "0" and
45+
not co.getRightOperand().getValue() = "1"
46+
)
47+
}
48+
49+
from Expr exp
50+
where
51+
incrementBoolType(exp) or
52+
revertSignBoolType(exp) or
53+
assignBoolType(exp)
54+
select exp, "this expression needs attention"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
| test.cpp:10:8:10:10 | - ... | this expression needs attention |
2+
| test.cpp:12:3:12:6 | ... ++ | this expression needs attention |
3+
| test.cpp:13:3:13:6 | ++ ... | this expression needs attention |
4+
| test.cpp:14:6:14:21 | ... = ... | this expression needs attention |
5+
| test.cpp:16:6:16:21 | ... = ... | this expression needs attention |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.ql
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
int tmpFunc()
2+
{
3+
return 12;
4+
}
5+
void testFunction()
6+
{
7+
int i1,i2,i3;
8+
bool b1,b2,b3;
9+
char c1,c2,c3;
10+
b1 = -b2; //BAD
11+
b1 = !b2; //GOOD
12+
b1++; //BAD
13+
++b1; //BAD
14+
if(i1=tmpFunc()!=i2) //BAD
15+
return;
16+
if(i1=tmpFunc()!=11) //BAD
17+
return;
18+
if((i1=tmpFunc())!=i2) //GOOD
19+
return;
20+
if((i1=tmpFunc())!=11) //GOOD
21+
return;
22+
if(i1=tmpFunc()!=1) //GOOD
23+
return;
24+
if(i1=tmpFunc()==b1) //GOOD
25+
return;
26+
}

0 commit comments

Comments
 (0)