Skip to content

Commit afcde14

Browse files
authored
Merge pull request #2085 from aschackmull/java/overflow-check-fp
Java: Add another overflow check pattern to UselessComparisonTest.
2 parents 0ad802b + 582a91f commit afcde14

File tree

3 files changed

+47
-15
lines changed

3 files changed

+47
-15
lines changed

change-notes/1.23/analysis-java.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The following changes in version 1.23 affect Java analysis in all applications.
1111
| Query built from user-controlled sources (`java/sql-injection`) | More results | The query now identifies arguments to `Statement.executeLargeUpdate` and `Connection.prepareCall` as SQL expressions sinks. |
1212
| Query built from local-user-controlled sources (`java/sql-injection-local`) | More results | The query now identifies arguments to `Statement.executeLargeUpdate` and `Connection.prepareCall` as SQL expressions sinks. |
1313
| Query built without neutralizing special characters (`java/concatenated-sql-query`) | More results | The query now identifies arguments to `Statement.executeLargeUpdate` and `Connection.prepareCall` as SQL expressions sinks. |
14+
| Useless comparison test (`java/constant-comparison`) | Fewer false positives | Additional overflow check patterns are now recognized and no longer reported. |
1415

1516
## Changes to QL libraries
1617

java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.ql

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -134,37 +134,48 @@ Expr overFlowCand() {
134134
result.(LocalVariableDeclExpr).getInit() = overFlowCand()
135135
}
136136

137-
/** Gets an expression that equals `v` plus a positive value. */
138-
Expr increaseOfVar(SsaVariable v) {
137+
predicate positiveOrNegative(Expr e) { positive(e) or negative(e) }
138+
139+
/** Gets an expression that equals `v` plus a positive or negative value. */
140+
Expr increaseOrDecreaseOfVar(SsaVariable v) {
139141
exists(AssignAddExpr add |
140142
result = add and
141-
positive(add.getDest()) and
143+
positiveOrNegative(add.getDest()) and
142144
add.getRhs() = v.getAUse()
143145
)
144146
or
145147
exists(AddExpr add, Expr e |
146148
result = add and
147149
add.hasOperands(v.getAUse(), e) and
148-
positive(e)
150+
positiveOrNegative(e)
149151
)
150152
or
151-
exists(SsaExplicitUpdate x | result = x.getAUse() and x.getDefiningExpr() = increaseOfVar(v))
153+
exists(SubExpr sub |
154+
result = sub and
155+
sub.getLeftOperand() = v.getAUse() and
156+
positiveOrNegative(sub.getRightOperand())
157+
)
152158
or
153-
result.(ParExpr).getExpr() = increaseOfVar(v)
159+
exists(SsaExplicitUpdate x |
160+
result = x.getAUse() and x.getDefiningExpr() = increaseOrDecreaseOfVar(v)
161+
)
154162
or
155-
result.(AssignExpr).getRhs() = increaseOfVar(v)
163+
result.(ParExpr).getExpr() = increaseOrDecreaseOfVar(v)
156164
or
157-
result.(LocalVariableDeclExpr).getInit() = increaseOfVar(v)
165+
result.(AssignExpr).getRhs() = increaseOrDecreaseOfVar(v)
166+
or
167+
result.(LocalVariableDeclExpr).getInit() = increaseOrDecreaseOfVar(v)
158168
}
159169

160170
predicate overFlowTest(ComparisonExpr comp) {
161-
exists(SsaVariable v |
162-
comp.getLesserOperand() = increaseOfVar(v) and
163-
comp.getGreaterOperand() = v.getAUse()
164-
)
165-
or
166-
comp.getLesserOperand() = overFlowCand() and
167-
comp.getGreaterOperand().(IntegerLiteral).getIntValue() = 0
171+
(
172+
exists(SsaVariable v | comp.hasOperands(increaseOrDecreaseOfVar(v), v.getAUse()))
173+
or
174+
comp.getLesserOperand() = overFlowCand() and
175+
comp.getGreaterOperand().(IntegerLiteral).getIntValue() = 0
176+
) and
177+
// exclude loop conditions as they are unlikely to be overflow tests
178+
not comp.getEnclosingStmt() instanceof LoopStmt
168179
}
169180

170181
predicate concurrentModificationTest(BinaryExpr test) {

java/ql/test/query-tests/UselessComparisonTest/A.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,26 @@ void overflowTests(int x, int y) {
121121
}
122122
}
123123

124+
static final long VAL = 100L;
125+
126+
long overflowAwareIncrease(long x) {
127+
if (x + VAL > x) {
128+
return x + VAL;
129+
} else {
130+
overflow();
131+
return Long.MAX_VALUE;
132+
}
133+
}
134+
135+
long overflowAwareDecrease(long x) {
136+
if (x - VAL < x) {
137+
return x - VAL;
138+
} else {
139+
overflow();
140+
return Long.MIN_VALUE;
141+
}
142+
}
143+
124144
void overflow() { }
125145

126146
void unreachableCode() {

0 commit comments

Comments
 (0)