1212 * external/cwe/cwe-570
1313 * external/cwe/cwe-571
1414 */
15+
1516import semmle.code.java.controlflow.Guards
1617import semmle.code.java.dataflow.SSA
1718import semmle.code.java.dataflow.SignAnalysis
1819import semmle.code.java.dataflow.RangeAnalysis
1920
2021/** Holds if `cond` always evaluates to `isTrue`. */
2122predicate constCond ( BinaryExpr cond , boolean isTrue , Reason reason ) {
22- exists ( ComparisonExpr comp , Expr lesser , Expr greater , Bound b , int d1 , int d2 , Reason r1 , Reason r2 |
23+ exists (
24+ ComparisonExpr comp , Expr lesser , Expr greater , Bound b , int d1 , int d2 , Reason r1 , Reason r2
25+ |
2326 comp = cond and
2427 lesser = comp .getLesserOperand ( ) and
2528 greater = comp .getGreaterOperand ( ) and
2629 bounded ( lesser , b , d1 , isTrue , r1 ) and
2730 bounded ( greater , b , d2 , isTrue .booleanNot ( ) , r2 ) and
2831 ( reason = r1 or reason = r2 ) and
29- ( r1 instanceof NoReason and r2 instanceof NoReason or not reason instanceof NoReason )
30- |
31- isTrue = true and comp .isStrict ( ) and d1 < d2 or
32- isTrue = true and not comp .isStrict ( ) and d1 <= d2 or
33- isTrue = false and comp .isStrict ( ) and d1 >= d2 or
32+ (
33+ r1 instanceof NoReason and r2 instanceof NoReason
34+ or
35+ not reason instanceof NoReason
36+ )
37+ |
38+ isTrue = true and comp .isStrict ( ) and d1 < d2
39+ or
40+ isTrue = true and not comp .isStrict ( ) and d1 <= d2
41+ or
42+ isTrue = false and comp .isStrict ( ) and d1 >= d2
43+ or
3444 isTrue = false and not comp .isStrict ( ) and d1 > d2
35- ) or
45+ )
46+ or
3647 exists ( EqualityTest eq , Expr lhs , Expr rhs |
3748 eq = cond and
3849 lhs = eq .getLeftOperand ( ) and
3950 rhs = eq .getRightOperand ( )
40- |
51+ |
4152 exists ( Bound b , int d1 , int d2 , boolean upper , Reason r1 , Reason r2 |
4253 bounded ( lhs , b , d1 , upper , r1 ) and
4354 bounded ( rhs , b , d2 , upper .booleanNot ( ) , r2 ) and
4455 isTrue = eq .polarity ( ) .booleanNot ( ) and
4556 ( reason = r1 or reason = r2 ) and
46- ( r1 instanceof NoReason and r2 instanceof NoReason or not reason instanceof NoReason )
47- |
48- upper = true and d1 < d2 or // lhs <= b + d1 < b + d2 <= rhs
49- upper = false and d1 > d2 // lhs >= b + d1 > b + d2 >= rhs
50- ) or
57+ (
58+ r1 instanceof NoReason and r2 instanceof NoReason
59+ or
60+ not reason instanceof NoReason
61+ )
62+ |
63+ upper = true and d1 < d2 // lhs <= b + d1 < b + d2 <= rhs
64+ or
65+ upper = false and d1 > d2 // lhs >= b + d1 > b + d2 >= rhs
66+ )
67+ or
5168 exists ( Bound b , int d , Reason r1 , Reason r2 , Reason r3 , Reason r4 |
5269 bounded ( lhs , b , d , true , r1 ) and
5370 bounded ( lhs , b , d , false , r2 ) and
5471 bounded ( rhs , b , d , true , r3 ) and
5572 bounded ( rhs , b , d , false , r4 ) and
5673 isTrue = eq .polarity ( )
57- |
74+ |
5875 ( reason = r1 or reason = r2 or reason = r3 or reason = r4 ) and
59- ( r1 instanceof NoReason and r2 instanceof NoReason and r3 instanceof NoReason and r4 instanceof NoReason or
60- not reason instanceof NoReason )
76+ (
77+ r1 instanceof NoReason and
78+ r2 instanceof NoReason and
79+ r3 instanceof NoReason and
80+ r4 instanceof NoReason
81+ or
82+ not reason instanceof NoReason
83+ )
6184 )
6285 )
6386}
@@ -73,34 +96,41 @@ Expr overFlowCand() {
7396 result = bin and
7497 positive ( bin .getLeftOperand ( ) ) and
7598 positive ( bin .getRightOperand ( ) )
76- |
99+ |
77100 bin instanceof AddExpr or
78101 bin instanceof MulExpr or
79102 bin instanceof LShiftExpr
80- ) or
103+ )
104+ or
81105 exists ( AssignOp op |
82106 result = op and
83107 positive ( op .getDest ( ) ) and
84108 positive ( op .getRhs ( ) )
85- |
109+ |
86110 op instanceof AssignAddExpr or
87111 op instanceof AssignMulExpr or
88112 op instanceof AssignLShiftExpr
89- ) or
113+ )
114+ or
90115 exists ( AddExpr add , CompileTimeConstantExpr c |
91116 result = add and
92117 add .hasOperands ( overFlowCand ( ) , c ) and
93118 c .getIntValue ( ) >= 0
94- ) or
119+ )
120+ or
95121 exists ( AssignAddExpr add , CompileTimeConstantExpr c |
96122 result = add and
97123 add .getDest ( ) = overFlowCand ( ) and
98124 add .getRhs ( ) = c and
99125 c .getIntValue ( ) >= 0
100- ) or
101- exists ( SsaExplicitUpdate x | result = x .getAUse ( ) and x .getDefiningExpr ( ) = overFlowCand ( ) ) or
102- result .( ParExpr ) .getExpr ( ) = overFlowCand ( ) or
103- result .( AssignExpr ) .getRhs ( ) = overFlowCand ( ) or
126+ )
127+ or
128+ exists ( SsaExplicitUpdate x | result = x .getAUse ( ) and x .getDefiningExpr ( ) = overFlowCand ( ) )
129+ or
130+ result .( ParExpr ) .getExpr ( ) = overFlowCand ( )
131+ or
132+ result .( AssignExpr ) .getRhs ( ) = overFlowCand ( )
133+ or
104134 result .( LocalVariableDeclExpr ) .getInit ( ) = overFlowCand ( )
105135}
106136
@@ -110,28 +140,33 @@ Expr increaseOfVar(SsaVariable v) {
110140 result = add and
111141 positive ( add .getDest ( ) ) and
112142 add .getRhs ( ) = v .getAUse ( )
113- ) or
143+ )
144+ or
114145 exists ( AddExpr add , Expr e |
115146 result = add and
116147 add .hasOperands ( v .getAUse ( ) , e ) and
117148 positive ( e )
118- ) or
119- exists ( SsaExplicitUpdate x | result = x .getAUse ( ) and x .getDefiningExpr ( ) = increaseOfVar ( v ) ) or
120- result .( ParExpr ) .getExpr ( ) = increaseOfVar ( v ) or
121- result .( AssignExpr ) .getRhs ( ) = increaseOfVar ( v ) or
149+ )
150+ or
151+ exists ( SsaExplicitUpdate x | result = x .getAUse ( ) and x .getDefiningExpr ( ) = increaseOfVar ( v ) )
152+ or
153+ result .( ParExpr ) .getExpr ( ) = increaseOfVar ( v )
154+ or
155+ result .( AssignExpr ) .getRhs ( ) = increaseOfVar ( v )
156+ or
122157 result .( LocalVariableDeclExpr ) .getInit ( ) = increaseOfVar ( v )
123158}
124159
125160predicate overFlowTest ( ComparisonExpr comp ) {
126161 exists ( SsaVariable v |
127162 comp .getLesserOperand ( ) = increaseOfVar ( v ) and
128163 comp .getGreaterOperand ( ) = v .getAUse ( )
129- ) or
164+ )
165+ or
130166 comp .getLesserOperand ( ) = overFlowCand ( ) and
131167 comp .getGreaterOperand ( ) .( IntegerLiteral ) .getIntValue ( ) = 0
132168}
133169
134-
135170/**
136171 * Holds if `test` and `guard` are equality tests of the same integral variable v with constants `c1` and `c2`.
137172 */
@@ -160,12 +195,20 @@ predicate uselessEqTest(EqualityTest test, boolean testIsTrue, Guard guard) {
160195from BinaryExpr test , boolean testIsTrue , string reason , ExprParent reasonElem
161196where
162197 (
163- if uselessEqTest ( test , _, _) then
164- exists ( EqualityTest r | uselessEqTest ( test , testIsTrue , r ) and reason = ", because of $@" and reasonElem = r )
165- else if constCondSimple ( test , _) then
166- ( constCondSimple ( test , testIsTrue ) and reason = "" and reasonElem = test ) // dummy reason element
198+ if uselessEqTest ( test , _, _)
199+ then
200+ exists ( EqualityTest r |
201+ uselessEqTest ( test , testIsTrue , r ) and reason = ", because of $@" and reasonElem = r
202+ )
167203 else
168- exists ( CondReason r | constCond ( test , testIsTrue , r ) and reason = ", because of $@" and reasonElem = r .getCond ( ) )
204+ if constCondSimple ( test , _)
205+ then (
206+ constCondSimple ( test , testIsTrue ) and reason = "" and reasonElem = test
207+ ) else
208+ // dummy reason element
209+ exists ( CondReason r |
210+ constCond ( test , testIsTrue , r ) and reason = ", because of $@" and reasonElem = r .getCond ( )
211+ )
169212 ) and
170213 not overFlowTest ( test ) and
171214 not exists ( AssertStmt assert | assert .getExpr ( ) = test .getParent * ( ) )
0 commit comments