Skip to content

Commit e725057

Browse files
committed
CPP: Check for a range check before the use.
1 parent 6cdfaee commit e725057

File tree

3 files changed

+29
-14
lines changed

3 files changed

+29
-14
lines changed

cpp/ql/src/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,29 @@
1313

1414
import cpp
1515

16-
from Variable v, LogicalAndExpr andexpr, ArrayExpr access, LTExpr rangecheck
17-
where access.getArrayOffset() = v.getAnAccess()
18-
and andexpr.getLeftOperand().getAChild*() = access
19-
and andexpr.getRightOperand() = rangecheck
20-
and rangecheck.getLeftOperand() = v.getAnAccess()
21-
and not access.isInMacroExpansion()
16+
predicate beforeArrayAccess(Variable v, ArrayExpr access, Expr before) {
17+
exists(LogicalAndExpr andexpr |
18+
access.getArrayOffset() = v.getAnAccess() and
19+
andexpr.getRightOperand().getAChild*() = access and
20+
andexpr.getLeftOperand() = before
21+
)
22+
}
23+
24+
predicate afterArrayAccess(Variable v, ArrayExpr access, Expr after) {
25+
exists(LogicalAndExpr andexpr |
26+
access.getArrayOffset() = v.getAnAccess() and
27+
andexpr.getLeftOperand().getAChild*() = access and
28+
andexpr.getRightOperand() = after
29+
)
30+
}
31+
32+
from Variable v, ArrayExpr access, LTExpr rangecheck
33+
where
34+
afterArrayAccess(v, access, rangecheck) and
35+
rangecheck.getLeftOperand() = v.getAnAccess() and
36+
not access.isInMacroExpansion() and
37+
not exists(LTExpr altcheck |
38+
beforeArrayAccess(v, access, altcheck) and
39+
altcheck.getLeftOperand() = v.getAnAccess()
40+
)
2241
select access, "This use of offset '" + v.getName() + "' should follow the $@.", rangecheck, "range check"
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
| test.cpp:11:10:11:18 | access to array | This use of offset 'i' should follow the $@. | test.cpp:11:32:11:45 | ... < ... | range check |
22
| test.cpp:15:7:15:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:15:29:15:42 | ... < ... | range check |
33
| test.cpp:27:7:27:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:27:39:27:52 | ... < ... | range check |
4-
| test.cpp:32:27:32:35 | access to array | This use of offset 'i' should follow the $@. | test.cpp:32:49:32:66 | ... < ... | range check |
5-
| test.cpp:33:28:33:36 | access to array | This use of offset 'i' should follow the $@. | test.cpp:33:50:33:67 | ... < ... | range check |
6-
| test.cpp:34:31:34:39 | access to array | This use of offset 'i' should follow the $@. | test.cpp:34:53:34:66 | ... < ... | range check |
7-
| test.cpp:35:32:35:40 | access to array | This use of offset 'i' should follow the $@. | test.cpp:35:54:35:67 | ... < ... | range check |
84
| test.cpp:39:8:39:16 | access to array | This use of offset 'i' should follow the $@. | test.cpp:39:30:39:47 | ... < ... | range check |
95
| test.cpp:44:7:44:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:44:22:44:35 | ... < ... | range check |
106
| test.cpp:47:7:47:15 | access to array | This use of offset 'i' should follow the $@. | test.cpp:47:33:47:46 | ... < ... | range check |

cpp/ql/test/query-tests/Best Practices/Likely Errors/OffsetUseBeforeRangeCheck/test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ void test(char *buffer, int bufferSize)
2929
if ((i < bufferSize - 1) && (buffer[i + 1] == 'x')) {} // GOOD
3030
if ((buffer[i + 1] == 'x') && (i < bufferSize - 1)) {} // BAD [NOT DETECTED]
3131

32-
if ((i < bufferSize) && (buffer[i] == 'x') && (i < bufferSize - 1)) {} // GOOD [FALSE POSITIVE]
33-
if ((i < bufferSize) && ((buffer[i] == 'x') && (i < bufferSize - 1))) {} // GOOD [FALSE POSITIVE]
34-
if ((i < bufferSize + 1) && (buffer[i] == 'x') && (i < bufferSize)) {} // BAD
35-
if ((i < bufferSize + 1) && ((buffer[i] == 'x') && (i < bufferSize))) {} // BAD
32+
if ((i < bufferSize) && (buffer[i] == 'x') && (i < bufferSize - 1)) {} // GOOD
33+
if ((i < bufferSize) && ((buffer[i] == 'x') && (i < bufferSize - 1))) {} // GOOD
34+
if ((i < bufferSize + 1) && (buffer[i] == 'x') && (i < bufferSize)) {} // BAD [NOT DETECTED]
35+
if ((i < bufferSize + 1) && ((buffer[i] == 'x') && (i < bufferSize))) {} // BAD [NOT DETECTED]
3636

3737
// look for 'ab'
3838
for (i = 0; i < bufferSize; i++) {

0 commit comments

Comments
 (0)