Skip to content

Commit a7410e4

Browse files
committed
Java: Fix bad join
Before ``` [2024-08-06 10:37:59] Evaluated non-recursive predicate BoundingChecks::arrayReference/1#754911ba@0628dahn in 20981ms (size: 2009682526). Evaluated relational algebra for predicate BoundingChecks::arrayReference/1#754911ba@0628dahn with tuple counts: 94480 ~0% {2} r1 = SCAN `Expr::ArrayAccess.getArray/0#dispred#b90c658a` OUTPUT In.1, In.0 32 ~0% {2} r2 = JOIN r1 WITH `Expr::MethodCall.getMethod/0#dispred#41989dc9` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 1013 ~1% {2} | JOIN WITH `Expr::MethodCall.getMethod/0#dispred#41989dc9_10#join_rhs` ON FIRST 1 OUTPUT Lhs.1, Rhs.1 92091 ~4% {2} r3 = JOIN r1 WITH variableBinding ON FIRST 1 OUTPUT Rhs.1, Lhs.1 2009681513 ~0% {2} | JOIN WITH variableBinding_10#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.1 2009682526 ~0% {2} r4 = r2 UNION r3 return r4 [2024-08-06 10:38:02] Evaluated non-recursive predicate BoundingChecks::lessthanLength/1#48b5e1b7@2885308n in 0ms (size: 108). Evaluated relational algebra for predicate BoundingChecks::lessthanLength/1#48b5e1b7@2885308n with tuple counts: 1518 ~0% {2} r1 = JOIN `Expr::ComparisonExpr.isStrict/0#dispred#fd8c6ddb` WITH `Expr::ComparisonExpr.getGreaterOperand/0#dispred#e8df4b14` ON FIRST 1 OUTPUT Rhs.1, Lhs.0 455 ~2% {2} | JOIN WITH Expr::FieldAccess#2b664c37 ON FIRST 1 OUTPUT Lhs.1, Lhs.0 455 ~1% {3} | JOIN WITH `Expr::ComparisonExpr.getLesserOperand/0#dispred#d7744bc2` ON FIRST 1 OUTPUT Lhs.1, Lhs.0, Rhs.1 455 ~0% {5} | JOIN WITH `Expr::FieldAccess.getField/0#dispred#29ef4aa0` ON FIRST 1 OUTPUT Rhs.1, _, Lhs.1, Lhs.0, Lhs.2 455 ~0% {5} | REWRITE WITH Out.1 := "length" 116 ~0% {3} | JOIN WITH `Element::Element.hasName/1#dispred#8acbbbde` ON FIRST 2 OUTPUT Lhs.4, Lhs.2, Lhs.3 93 ~0% {3} | JOIN WITH variableBinding ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1 93 ~1% {3} | JOIN WITH `Expr::VarAccess.getQualifier/0#dispred#2b0f1cd1` ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1 484 ~2% {3} | JOIN WITH variableBinding_10#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2 277 ~3% {2} | JOIN WITH `BoundingChecks::conditionHolds/2#fa0354b9#bb` ON FIRST 2 OUTPUT Lhs.1, Lhs.2 166 ~5% {2} | JOIN WITH `Expr::ArrayAccess.getIndexExpr/0#dispred#345f6cf4_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 110 ~0% {1} | JOIN WITH `BoundingChecks::arrayReference/1#754911ba` ON FIRST 2 OUTPUT Lhs.0 return r1 ``` After ``` [2024-08-06 13:29:50] Evaluated non-recursive predicate BoundingChecks::lengthAccess/2#54b10eff@719e68tb in 0ms (size: 309). Evaluated relational algebra for predicate BoundingChecks::lengthAccess/2#54b10eff@719e68tb with tuple counts: 6241 ~0% {2} r1 = JOIN `BoundingChecks::getAnAccess/1#152ad44e_10#join_rhs` WITH `Expr::VarAccess.getQualifier/0#dispred#2b0f1cd1_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 6240 ~0% {4} | JOIN WITH `Expr::FieldAccess.getField/0#dispred#29ef4aa0` ON FIRST 1 OUTPUT Rhs.1, _, Lhs.1, Lhs.0 6240 ~0% {4} | REWRITE WITH Out.1 := "length" 309 ~2% {2} | JOIN WITH `Element::Element.hasName/1#dispred#8acbbbde` ON FIRST 2 OUTPUT Lhs.3, Lhs.2 return r1 [2024-08-06 13:29:50] Evaluated non-recursive predicate BoundingChecks::lessthanLength/1#48b5e1b7@0fcac509 in 1ms (size: 108). Evaluated relational algebra for predicate BoundingChecks::lessthanLength/1#48b5e1b7@0fcac509 with tuple counts: 94480 ~0% {3} r1 = JOIN `Expr::ArrayAccess.getArray/0#dispred#b90c658a` WITH `Expr::ArrayAccess.getIndexExpr/0#dispred#345f6cf4` ON FIRST 1 OUTPUT Rhs.1, Lhs.0, Lhs.1 648 ~4% {4} | JOIN WITH variableBinding ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.0, Rhs.1 621 ~1% {4} | JOIN WITH `BoundingChecks::getAnAccess/1#152ad44e_10#join_rhs` ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.3, Rhs.1 344 ~0% {4} | JOIN WITH `BoundingChecks::conditionHolds/2#fa0354b9#bb_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3 341 ~0% {4} | JOIN WITH `Expr::ComparisonExpr.isStrict/0#dispred#fd8c6ddb` ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.3 341 ~0% {5} | JOIN WITH `Expr::ComparisonExpr.getGreaterOperand/0#dispred#e8df4b14` ON FIRST 1 OUTPUT Rhs.1, Lhs.3, Lhs.1, Lhs.2, Lhs.0 110 ~2% {3} | JOIN WITH `BoundingChecks::lengthAccess/2#54b10eff` ON FIRST 2 OUTPUT Lhs.4, Lhs.2, Lhs.3 110 ~0% {3} | JOIN WITH `Expr::ComparisonExpr.getLesserOperand/0#dispred#d7744bc2` ON FIRST 1 OUTPUT Rhs.1, Lhs.2, Lhs.1 110 ~0% {1} | JOIN WITH variableBinding ON FIRST 2 OUTPUT Lhs.2 return r1 ```
1 parent 6273bb6 commit a7410e4

File tree

1 file changed

+17
-15
lines changed

1 file changed

+17
-15
lines changed

java/ql/lib/semmle/code/java/security/internal/BoundingChecks.qll

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,30 +36,32 @@ int lowerBound(VarAccess va) {
3636
)
3737
}
3838

39+
/** Gets an access to `e`, which is either a variable or a method. */
40+
pragma[nomagic]
41+
private Expr getAnAccess(Element e) {
42+
result = e.(Variable).getAnAccess()
43+
or
44+
result.(MethodCall).getMethod() = e
45+
}
46+
47+
pragma[nomagic]
48+
private predicate lengthAccess(FieldAccess fa, Element qualifier) {
49+
fa.getQualifier() = getAnAccess(qualifier) and
50+
fa.getField().hasName("length")
51+
}
52+
3953
/**
4054
* Holds if the index expression is a `VarAccess`, where the variable has been confirmed to be less
4155
* than the length.
4256
*/
4357
predicate lessthanLength(ArrayAccess a) {
44-
exists(ComparisonExpr lessThanLength, VarAccess va |
58+
exists(ComparisonExpr lessThanLength, VarAccess va, Element qualifier |
4559
va = a.getIndexExpr() and
4660
conditionHolds(lessThanLength, va)
4761
|
48-
lessThanLength.getGreaterOperand().(FieldAccess).getQualifier() = arrayReference(a) and
49-
lessThanLength.getGreaterOperand().(FieldAccess).getField().hasName("length") and
62+
lengthAccess(lessThanLength.getGreaterOperand(), qualifier) and
63+
a.getArray() = getAnAccess(qualifier) and
5064
lessThanLength.getLesserOperand() = va.getVariable().getAnAccess() and
5165
lessThanLength.isStrict()
5266
)
5367
}
54-
55-
/**
56-
* Return all other references to the array accessed in the `ArrayAccess`.
57-
*/
58-
pragma[nomagic]
59-
private Expr arrayReference(ArrayAccess arrayAccess) {
60-
// Array is stored in a variable.
61-
result = arrayAccess.getArray().(VarAccess).getVariable().getAnAccess()
62-
or
63-
// Array is returned from a method.
64-
result.(MethodCall).getMethod() = arrayAccess.getArray().(MethodCall).getMethod()
65-
}

0 commit comments

Comments
 (0)