Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8c6caf2

Browse files
committed
[CPP-434] Rename everything to SignedOverflowCheck. Add .qlhelp. Deal with addition only, not subtraction.
1 parent c9a9aff commit 8c6caf2

9 files changed

Lines changed: 57 additions & 23 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
bool foo(int n1, unsigned short delta) {
2+
return n1 + delta < n1; // BAD
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
bool bar(int n1, unsigned int delta) {
2+
return n1 + delta < n1; // GOOD
3+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>
7+
Testing for <code>signed</code> integer overflow by adding a
8+
value to a variable and then comparing the result to said variable
9+
is not defined by the C or C++ standards. The comparison may
10+
produce an unintended result, or may be deleted by the compiler
11+
entirely.
12+
</p>
13+
</overview>
14+
<recommendation>
15+
<p>
16+
Make sure that the comparison in question uses <i>unsigned</i> values.
17+
</p>
18+
</recommendation>
19+
<example>
20+
<p>
21+
In the following example, even though <code>delta</code> has been declared
22+
<code>unsigned short</code>, C/C++ type promotion rules require that its
23+
type is promoted to the larger type used in the addition and comparison,
24+
namely a <code>signed int</code>. As a result, the entire expression is
25+
evaluated using <code>signed values</code> and its value is therefore undefined.
26+
</p>
27+
<sample src="SignedOverflowCheck-bad.cpp" />
28+
<p>
29+
In the next example, a value of type <code>signed int</code> is
30+
getting added to a value ot type <code>unsigned int</code>. Because
31+
the types are of the same size, C/C++ promotion rules dictate that
32+
<code>unsigned int</code> is chosen as the overall type of the addition
33+
operation. The entire expression is evaluated using <code>unsigned</code>
34+
values, which is allowed and defined behavior per the C/C++ standard.
35+
</p>
36+
<sample src="SignedOverflowCheck-good.cpp" />
37+
</example>
38+
<references>
39+
<li><a href="http://c-faq.com/expr/preservingrules.html">Preserving Rules</a></li>
40+
<li><a href="https://www.securecoding.cert.org/confluence/plugins/servlet/mobile#content/view/20086942">Understand integer conversion rules</a></li>
41+
</references>
42+
</qhelp>

cpp/ql/src/Likely Bugs/Arithmetic/SignedComparisons.ql renamed to cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
/**
22
* @name Undefined result of signed test for overflow
3-
* @description Testing for signed integer overflow by adding a value to
4-
* a variable (or subtracting a value from a variable) and
5-
* then comparing the result to said variable is not defined
6-
* by the C or C++ standards. The comparison may produce an
7-
* unintended result, or may be deleted by the compiler
8-
* entirely.
3+
* @description Testing for oveflow by adding a value to a variable
4+
* to see if it "wraps around" works only for
5+
* `unsigned` integer values.
96
* @kind problem
107
* @problem.severity warning
118
* @precision medium
@@ -19,14 +16,14 @@ import cpp
1916
from RelationalOperation ro, BinaryArithmeticOperation bao, VariableAccess va1, VariableAccess va2
2017
where
2118
ro.getAnOperand() = bao and
22-
(bao instanceof AddExpr or bao instanceof SubExpr) and
19+
bao instanceof AddExpr and
2320
bao.getAnOperand() = va1 and
2421
ro.getAnOperand() = va2 and
2522
va1.getTarget() = va2.getTarget() and
2623
/*
2724
* if the addition/subtraction (`bao`) has been promoted to a signed type,
28-
* then the other operand (`va2`) must also be signed and we have a signed
29-
* comparison
25+
* then the other operand (`va2`) must have been likewise promoted and so
26+
* have a signed comparison
3027
*/
3128

3229
bao.getFullyConverted().getType().(IntegralType).isSigned()

cpp/ql/test/query-tests/Likely Bugs/Arithmetic/SignedComparisons/SignedComparisons.expected

Lines changed: 0 additions & 4 deletions
This file was deleted.

cpp/ql/test/query-tests/Likely Bugs/Arithmetic/SignedComparisons/SignedComparisons.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.

cpp/ql/test/query-tests/Likely Bugs/Arithmetic/SignedComparisons/SignedComparisons.cpp renamed to cpp/ql/test/query-tests/Likely Bugs/Arithmetic/SignedOverflowCheck/SignedOverflowCheck.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ bool cannotHoldAnother8(int n1) {
77
// msvc 19.22 /O2: not deleted
88
return n1 + 8 < n1; // BAD
99
}
10-
bool canHoldPreceding16(int n1) {
11-
return n1 - 16 < n1;
12-
}
1310

1411
/* 2. Signed comparison with a narrower unsigned type. The narrower
1512
type gets promoted to the (signed) larger type, and so the
@@ -20,9 +17,6 @@ bool cannotHoldAnotherUShort(int n1, unsigned short delta) {
2017
// msvc 19.22 /O2: not deleted
2118
return n1 + delta < n1; // BAD
2219
}
23-
bool canHoldPrecedingUShort(int n1, unsigned short delta) {
24-
return n1 - delta < n1;
25-
}
2620

2721
/* 3. Signed comparison with a non-narrower unsigned type. The
2822
signed type gets promoted to (a possibly wider) unsigned type,
@@ -33,6 +27,3 @@ bool cannotHoldAnotherUInt(int n1, unsigned int delta) {
3327
// msvc 19.22 /O2: not deleted
3428
return n1 + delta < n1; // GOOD
3529
}
36-
bool canHoldPrecedingUInt(int n1, unsigned int delta) {
37-
return n1 - delta < n1;
38-
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| SignedOverflowCheck.cpp:8:12:8:22 | ... < ... | Testing for signed overflow/underflow may produce undefined results. |
2+
| SignedOverflowCheck.cpp:18:12:18:26 | ... < ... | Testing for signed overflow/underflow may produce undefined results. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Likely Bugs/Arithmetic/SignedOverflowCheck.ql

0 commit comments

Comments
 (0)