diff --git a/java/src/security/Recursion/Recursion.ql b/java/src/security/Recursion/Recursion.ql index d795b10..931c871 100644 --- a/java/src/security/Recursion/Recursion.ql +++ b/java/src/security/Recursion/Recursion.ql @@ -13,7 +13,6 @@ import java import semmle.code.java.dataflow.DataFlow - predicate isTestPackage(RefType referenceType) { referenceType.getPackage().getName().toLowerCase().matches("%test%") or referenceType.getPackage().getName().toLowerCase().matches("%benchmark%") or @@ -24,11 +23,25 @@ class RecursionSource extends MethodCall { RecursionSource() { not isTestPackage(this.getCaller().getDeclaringType()) } override string toString() { - result = this.getCaller().toString() + " calls " + this.getCallee().toString() + result = this.getCaller().toString() + " clls " + this.getCallee().toString() } } +/** + * Check if the Expr uses directly an argument of the enclosing function + */ +class ParameterOperation extends Expr { + ParameterOperation() { + this instanceof BinaryExpr or this instanceof UnaryAssignExpr + and exists( + VarAccess va | + va.getVariable() = this.getEnclosingCallable().getAParameter() | + this.getAChildExpr+() = va + ) + } +} + module RecursiveConfig implements DataFlow::StateConfigSig { class FlowState = Method; @@ -44,12 +57,26 @@ module RecursiveConfig implements DataFlow::StateConfigSig { } predicate isBarrier(DataFlow::Node node) { - node.asExpr() instanceof MethodCall and - exists(Expr arg | arg = node.asExpr().(MethodCall).getAnArgument() | - arg instanceof BinaryExpr or - exists(BinaryExpr b | DataFlow::localFlow(DataFlow::exprNode(b), DataFlow::exprNode(arg))) + exists(MethodCall ma | + ma = node.asExpr() + and ( + exists(Expr e | e = ma.getAnArgument() and e instanceof ParameterOperation) + // or exists( + // VarAccess e| + // e = ma.getAnArgument() | + // e.getVariable().getAnAssignedValue().getAChildExpr() instanceof ParameterOperation + // ) + ) ) } + + /** + * Weird but useful deduplication logic + */ + predicate isBarrierIn(DataFlow::Node node, FlowState state) { + not node.asExpr() instanceof MethodCall + or node.asExpr().(MethodCall).getCaller().getLocation().getStartLine() > state.getLocation().getStartLine() + } } module RecursiveFlow = DataFlow::GlobalWithState; @@ -66,4 +93,4 @@ import RecursiveFlow::PathGraph from RecursiveFlow::PathNode source, RecursiveFlow::PathNode sink where RecursiveFlow::flowPath(source, sink) // TODO(dm): de-duplicate results -select sink.getNode(), source, sink, "Found a recursion: " +select sink.getNode(), source, sink, "Found a recursion: " \ No newline at end of file diff --git a/java/test/query-tests/security/Recursion/Recursion.expected b/java/test/query-tests/security/Recursion/Recursion.expected index b34aa1c..61c3080 100644 --- a/java/test/query-tests/security/Recursion/Recursion.expected +++ b/java/test/query-tests/security/Recursion/Recursion.expected @@ -1,153 +1,67 @@ edges -| Recursion.java:53:33:53:55 | readToken calls read : Token | Recursion.java:59:24:59:28 | token : Token | provenance | | -| Recursion.java:57:24:57:34 | readToken calls readToken : Token | Recursion.java:57:24:57:34 | readToken calls readToken | provenance | | -| Recursion.java:57:24:57:34 | readToken calls readToken : Token | Recursion.java:57:24:57:34 | readToken calls readToken : Token | provenance | | -| Recursion.java:59:24:59:28 | token : Token | Recursion.java:57:24:57:34 | readToken calls readToken | provenance | | -| Recursion.java:59:24:59:28 | token : Token | Recursion.java:57:24:57:34 | readToken calls readToken : Token | provenance | | -| Recursion.java:71:29:71:33 | bar calls foo : Boolean | Recursion.java:72:16:72:24 | fooResult : Boolean | provenance | | -| Recursion.java:71:29:71:33 | bar calls foo : Boolean | Recursion.java:72:16:72:24 | fooResult : Boolean | provenance | | -| Recursion.java:72:16:72:24 | fooResult : Boolean | Recursion.java:76:16:76:20 | foo calls bar | provenance | | -| Recursion.java:72:16:72:24 | fooResult : Boolean | Recursion.java:76:16:76:20 | foo calls bar : Boolean | provenance | | -| Recursion.java:72:16:72:24 | fooResult : Boolean | Recursion.java:76:16:76:20 | foo calls bar : Boolean | provenance | | -| Recursion.java:76:16:76:20 | foo calls bar : Boolean | Recursion.java:71:29:71:33 | bar calls foo | provenance | | -| Recursion.java:76:16:76:20 | foo calls bar : Boolean | Recursion.java:71:29:71:33 | bar calls foo : Boolean | provenance | | -| Recursion.java:76:16:76:20 | foo calls bar : Boolean | Recursion.java:71:29:71:33 | bar calls foo : Boolean | provenance | | -| Recursion.java:81:16:81:32 | directRecursive calls directRecursive : Boolean | Recursion.java:81:16:81:32 | directRecursive calls directRecursive | provenance | | -| Recursion.java:81:16:81:32 | directRecursive calls directRecursive : Boolean | Recursion.java:81:16:81:32 | directRecursive calls directRecursive : Boolean | provenance | | -| Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | Recursion.java:101:16:101:23 | level2 calls level0 | provenance | | -| Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | provenance | | -| Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | provenance | | -| Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | provenance | | -| Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | Recursion.java:89:16:89:23 | level0 calls level1 | provenance | | -| Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | provenance | | -| Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | provenance | | -| Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | provenance | | -| Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | Recursion.java:95:16:95:23 | level1 calls level2 | provenance | | -| Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | provenance | | -| Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | provenance | | -| Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | provenance | | -| Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth : Boolean | Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth | provenance | | -| Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth : Boolean | Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth : Boolean | provenance | | -| Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 | provenance | | -| Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 | provenance | | -| Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | provenance | | -| Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | provenance | | -| Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | provenance | | -| Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 | provenance | | -| Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 | provenance | | -| Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | provenance | | -| Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | provenance | | -| Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | provenance | | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:184:20:184:27 | level0 calls level1 | provenance | | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | provenance | | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | provenance | | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | provenance | | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:196:20:196:27 | level2 calls level1 | provenance | | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | provenance | | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | provenance | | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | provenance | | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 | provenance | | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 | provenance | | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | provenance | | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | provenance | | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | provenance | | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 | provenance | | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 | provenance | | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | provenance | | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | provenance | | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | provenance | | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 | provenance | | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 | provenance | | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | provenance | | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | provenance | | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | provenance | | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 | provenance | | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 | provenance | | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | provenance | | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | provenance | | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | provenance | | +| Recursion.java:57:24:57:34 | readToken clls readToken : Token | Recursion.java:57:24:57:34 | readToken clls readToken | provenance | | +| Recursion.java:57:24:57:34 | readToken clls readToken : Token | Recursion.java:57:24:57:34 | readToken clls readToken : Token | provenance | | +| Recursion.java:81:16:81:32 | directRecursive clls directRecursive : Boolean | Recursion.java:81:16:81:32 | directRecursive clls directRecursive | provenance | | +| Recursion.java:81:16:81:32 | directRecursive clls directRecursive : Boolean | Recursion.java:81:16:81:32 | directRecursive clls directRecursive : Boolean | provenance | | +| Recursion.java:89:16:89:23 | level0 clls level1 : Boolean | Recursion.java:101:16:101:23 | level2 clls level0 : Boolean | provenance | | +| Recursion.java:95:16:95:23 | level1 clls level2 : Boolean | Recursion.java:89:16:89:23 | level0 clls level1 | provenance | | +| Recursion.java:95:16:95:23 | level1 clls level2 : Boolean | Recursion.java:89:16:89:23 | level0 clls level1 : Boolean | provenance | | +| Recursion.java:101:16:101:23 | level2 clls level0 : Boolean | Recursion.java:95:16:95:23 | level1 clls level2 : Boolean | provenance | | +| Recursion.java:116:20:116:27 | level0 clls level1 : Boolean | Recursion.java:130:16:130:23 | level2 clls level0 | provenance | | +| Recursion.java:116:20:116:27 | level0 clls level1 : Boolean | Recursion.java:130:16:130:23 | level2 clls level0 : Boolean | provenance | | +| Recursion.java:118:16:118:23 | level0 clls level2 : Boolean | Recursion.java:130:16:130:23 | level2 clls level0 | provenance | | +| Recursion.java:118:16:118:23 | level0 clls level2 : Boolean | Recursion.java:130:16:130:23 | level2 clls level0 : Boolean | provenance | | +| Recursion.java:124:16:124:23 | level1 clls level2 : Boolean | Recursion.java:116:20:116:27 | level0 clls level1 | provenance | | +| Recursion.java:124:16:124:23 | level1 clls level2 : Boolean | Recursion.java:116:20:116:27 | level0 clls level1 : Boolean | provenance | | +| Recursion.java:124:16:124:23 | level1 clls level2 : Boolean | Recursion.java:128:20:128:27 | level2 clls level1 | provenance | | +| Recursion.java:124:16:124:23 | level1 clls level2 : Boolean | Recursion.java:128:20:128:27 | level2 clls level1 : Boolean | provenance | | +| Recursion.java:128:20:128:27 | level2 clls level1 : Boolean | Recursion.java:118:16:118:23 | level0 clls level2 : Boolean | provenance | | +| Recursion.java:128:20:128:27 | level2 clls level1 : Boolean | Recursion.java:124:16:124:23 | level1 clls level2 : Boolean | provenance | | +| Recursion.java:130:16:130:23 | level2 clls level0 : Boolean | Recursion.java:118:16:118:23 | level0 clls level2 : Boolean | provenance | | +| Recursion.java:130:16:130:23 | level2 clls level0 : Boolean | Recursion.java:124:16:124:23 | level1 clls level2 : Boolean | provenance | | +| Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth : Boolean | Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth | provenance | | +| Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth : Boolean | Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth : Boolean | provenance | | nodes -| Recursion.java:53:33:53:55 | readToken calls read : Token | semmle.label | readToken calls read : Token | -| Recursion.java:57:24:57:34 | readToken calls readToken | semmle.label | readToken calls readToken | -| Recursion.java:57:24:57:34 | readToken calls readToken : Token | semmle.label | readToken calls readToken : Token | -| Recursion.java:59:24:59:28 | token : Token | semmle.label | token : Token | -| Recursion.java:71:29:71:33 | bar calls foo | semmle.label | bar calls foo | -| Recursion.java:71:29:71:33 | bar calls foo : Boolean | semmle.label | bar calls foo : Boolean | -| Recursion.java:71:29:71:33 | bar calls foo : Boolean | semmle.label | bar calls foo : Boolean | -| Recursion.java:72:16:72:24 | fooResult : Boolean | semmle.label | fooResult : Boolean | -| Recursion.java:72:16:72:24 | fooResult : Boolean | semmle.label | fooResult : Boolean | -| Recursion.java:76:16:76:20 | foo calls bar | semmle.label | foo calls bar | -| Recursion.java:76:16:76:20 | foo calls bar : Boolean | semmle.label | foo calls bar : Boolean | -| Recursion.java:76:16:76:20 | foo calls bar : Boolean | semmle.label | foo calls bar : Boolean | -| Recursion.java:81:16:81:32 | directRecursive calls directRecursive | semmle.label | directRecursive calls directRecursive | -| Recursion.java:81:16:81:32 | directRecursive calls directRecursive : Boolean | semmle.label | directRecursive calls directRecursive : Boolean | -| Recursion.java:89:16:89:23 | level0 calls level1 | semmle.label | level0 calls level1 | -| Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | semmle.label | level0 calls level1 : Boolean | -| Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | semmle.label | level0 calls level1 : Boolean | -| Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | semmle.label | level0 calls level1 : Boolean | -| Recursion.java:95:16:95:23 | level1 calls level2 | semmle.label | level1 calls level2 | -| Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | semmle.label | level1 calls level2 : Boolean | -| Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | semmle.label | level1 calls level2 : Boolean | -| Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | semmle.label | level1 calls level2 : Boolean | -| Recursion.java:101:16:101:23 | level2 calls level0 | semmle.label | level2 calls level0 | -| Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | semmle.label | level2 calls level0 : Boolean | -| Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | semmle.label | level2 calls level0 : Boolean | -| Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | semmle.label | level2 calls level0 : Boolean | -| Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth | semmle.label | directRecursiveNoDepth calls directRecursiveNoDepth | -| Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth : Boolean | semmle.label | directRecursiveNoDepth calls directRecursiveNoDepth : Boolean | -| Recursion.java:184:20:184:27 | level0 calls level1 | semmle.label | level0 calls level1 | -| Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | semmle.label | level0 calls level1 : Boolean | -| Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | semmle.label | level0 calls level1 : Boolean | -| Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | semmle.label | level0 calls level1 : Boolean | -| Recursion.java:186:16:186:23 | level0 calls level2 | semmle.label | level0 calls level2 | -| Recursion.java:186:16:186:23 | level0 calls level2 | semmle.label | level0 calls level2 | -| Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | semmle.label | level0 calls level2 : Boolean | -| Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | semmle.label | level0 calls level2 : Boolean | -| Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | semmle.label | level0 calls level2 : Boolean | -| Recursion.java:192:16:192:23 | level1 calls level2 | semmle.label | level1 calls level2 | -| Recursion.java:192:16:192:23 | level1 calls level2 | semmle.label | level1 calls level2 | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | semmle.label | level1 calls level2 : Boolean | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | semmle.label | level1 calls level2 : Boolean | -| Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | semmle.label | level1 calls level2 : Boolean | -| Recursion.java:196:20:196:27 | level2 calls level1 | semmle.label | level2 calls level1 | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | semmle.label | level2 calls level1 : Boolean | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | semmle.label | level2 calls level1 : Boolean | -| Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | semmle.label | level2 calls level1 : Boolean | -| Recursion.java:198:16:198:23 | level2 calls level0 | semmle.label | level2 calls level0 | -| Recursion.java:198:16:198:23 | level2 calls level0 | semmle.label | level2 calls level0 | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | semmle.label | level2 calls level0 : Boolean | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | semmle.label | level2 calls level0 : Boolean | -| Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | semmle.label | level2 calls level0 : Boolean | +| Recursion.java:57:24:57:34 | readToken clls readToken | semmle.label | readToken clls readToken | +| Recursion.java:57:24:57:34 | readToken clls readToken : Token | semmle.label | readToken clls readToken : Token | +| Recursion.java:71:29:71:33 | bar clls foo | semmle.label | bar clls foo | +| Recursion.java:76:16:76:20 | foo clls bar | semmle.label | foo clls bar | +| Recursion.java:81:16:81:32 | directRecursive clls directRecursive | semmle.label | directRecursive clls directRecursive | +| Recursion.java:81:16:81:32 | directRecursive clls directRecursive : Boolean | semmle.label | directRecursive clls directRecursive : Boolean | +| Recursion.java:89:16:89:23 | level0 clls level1 | semmle.label | level0 clls level1 | +| Recursion.java:89:16:89:23 | level0 clls level1 : Boolean | semmle.label | level0 clls level1 : Boolean | +| Recursion.java:95:16:95:23 | level1 clls level2 : Boolean | semmle.label | level1 clls level2 : Boolean | +| Recursion.java:101:16:101:23 | level2 clls level0 : Boolean | semmle.label | level2 clls level0 : Boolean | +| Recursion.java:116:20:116:27 | level0 clls level1 | semmle.label | level0 clls level1 | +| Recursion.java:116:20:116:27 | level0 clls level1 : Boolean | semmle.label | level0 clls level1 : Boolean | +| Recursion.java:118:16:118:23 | level0 clls level2 | semmle.label | level0 clls level2 | +| Recursion.java:118:16:118:23 | level0 clls level2 : Boolean | semmle.label | level0 clls level2 : Boolean | +| Recursion.java:124:16:124:23 | level1 clls level2 | semmle.label | level1 clls level2 | +| Recursion.java:124:16:124:23 | level1 clls level2 : Boolean | semmle.label | level1 clls level2 : Boolean | +| Recursion.java:128:20:128:27 | level2 clls level1 | semmle.label | level2 clls level1 | +| Recursion.java:128:20:128:27 | level2 clls level1 : Boolean | semmle.label | level2 clls level1 : Boolean | +| Recursion.java:130:16:130:23 | level2 clls level0 | semmle.label | level2 clls level0 | +| Recursion.java:130:16:130:23 | level2 clls level0 : Boolean | semmle.label | level2 clls level0 : Boolean | +| Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth | semmle.label | directRecursiveNoDepth clls directRecursiveNoDepth | +| Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth : Boolean | semmle.label | directRecursiveNoDepth clls directRecursiveNoDepth : Boolean | subpaths #select -| Recursion.java:57:24:57:34 | readToken calls readToken | Recursion.java:53:33:53:55 | readToken calls read : Token | Recursion.java:57:24:57:34 | readToken calls readToken | Found a recursion: | -| Recursion.java:57:24:57:34 | readToken calls readToken | Recursion.java:57:24:57:34 | readToken calls readToken | Recursion.java:57:24:57:34 | readToken calls readToken | Found a recursion: | -| Recursion.java:57:24:57:34 | readToken calls readToken | Recursion.java:57:24:57:34 | readToken calls readToken : Token | Recursion.java:57:24:57:34 | readToken calls readToken | Found a recursion: | -| Recursion.java:71:29:71:33 | bar calls foo | Recursion.java:71:29:71:33 | bar calls foo | Recursion.java:71:29:71:33 | bar calls foo | Found a recursion: | -| Recursion.java:71:29:71:33 | bar calls foo | Recursion.java:71:29:71:33 | bar calls foo : Boolean | Recursion.java:71:29:71:33 | bar calls foo | Found a recursion: | -| Recursion.java:76:16:76:20 | foo calls bar | Recursion.java:76:16:76:20 | foo calls bar | Recursion.java:76:16:76:20 | foo calls bar | Found a recursion: | -| Recursion.java:76:16:76:20 | foo calls bar | Recursion.java:76:16:76:20 | foo calls bar : Boolean | Recursion.java:76:16:76:20 | foo calls bar | Found a recursion: | -| Recursion.java:81:16:81:32 | directRecursive calls directRecursive | Recursion.java:81:16:81:32 | directRecursive calls directRecursive | Recursion.java:81:16:81:32 | directRecursive calls directRecursive | Found a recursion: | -| Recursion.java:81:16:81:32 | directRecursive calls directRecursive | Recursion.java:81:16:81:32 | directRecursive calls directRecursive : Boolean | Recursion.java:81:16:81:32 | directRecursive calls directRecursive | Found a recursion: | -| Recursion.java:89:16:89:23 | level0 calls level1 | Recursion.java:101:16:101:23 | level2 calls level0 : Boolean | Recursion.java:89:16:89:23 | level0 calls level1 | Found a recursion: | -| Recursion.java:95:16:95:23 | level1 calls level2 | Recursion.java:89:16:89:23 | level0 calls level1 : Boolean | Recursion.java:95:16:95:23 | level1 calls level2 | Found a recursion: | -| Recursion.java:101:16:101:23 | level2 calls level0 | Recursion.java:95:16:95:23 | level1 calls level2 : Boolean | Recursion.java:101:16:101:23 | level2 calls level0 | Found a recursion: | -| Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth | Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth | Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth | Found a recursion: | -| Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth | Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth : Boolean | Recursion.java:115:16:115:54 | directRecursiveNoDepth calls directRecursiveNoDepth | Found a recursion: | -| Recursion.java:184:20:184:27 | level0 calls level1 | Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:184:20:184:27 | level0 calls level1 | Found a recursion: | -| Recursion.java:184:20:184:27 | level0 calls level1 | Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:184:20:184:27 | level0 calls level1 | Found a recursion: | -| Recursion.java:186:16:186:23 | level0 calls level2 | Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 | Found a recursion: | -| Recursion.java:186:16:186:23 | level0 calls level2 | Recursion.java:186:16:186:23 | level0 calls level2 | Recursion.java:186:16:186:23 | level0 calls level2 | Found a recursion: | -| Recursion.java:186:16:186:23 | level0 calls level2 | Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 | Found a recursion: | -| Recursion.java:186:16:186:23 | level0 calls level2 | Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:186:16:186:23 | level0 calls level2 | Found a recursion: | -| Recursion.java:192:16:192:23 | level1 calls level2 | Recursion.java:184:20:184:27 | level0 calls level1 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 | Found a recursion: | -| Recursion.java:192:16:192:23 | level1 calls level2 | Recursion.java:186:16:186:23 | level0 calls level2 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 | Found a recursion: | -| Recursion.java:192:16:192:23 | level1 calls level2 | Recursion.java:192:16:192:23 | level1 calls level2 | Recursion.java:192:16:192:23 | level1 calls level2 | Found a recursion: | -| Recursion.java:192:16:192:23 | level1 calls level2 | Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:192:16:192:23 | level1 calls level2 | Found a recursion: | -| Recursion.java:196:20:196:27 | level2 calls level1 | Recursion.java:196:20:196:27 | level2 calls level1 | Recursion.java:196:20:196:27 | level2 calls level1 | Found a recursion: | -| Recursion.java:196:20:196:27 | level2 calls level1 | Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:196:20:196:27 | level2 calls level1 | Found a recursion: | -| Recursion.java:196:20:196:27 | level2 calls level1 | Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:196:20:196:27 | level2 calls level1 | Found a recursion: | -| Recursion.java:198:16:198:23 | level2 calls level0 | Recursion.java:192:16:192:23 | level1 calls level2 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 | Found a recursion: | -| Recursion.java:198:16:198:23 | level2 calls level0 | Recursion.java:196:20:196:27 | level2 calls level1 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 | Found a recursion: | -| Recursion.java:198:16:198:23 | level2 calls level0 | Recursion.java:198:16:198:23 | level2 calls level0 | Recursion.java:198:16:198:23 | level2 calls level0 | Found a recursion: | -| Recursion.java:198:16:198:23 | level2 calls level0 | Recursion.java:198:16:198:23 | level2 calls level0 : Boolean | Recursion.java:198:16:198:23 | level2 calls level0 | Found a recursion: | +| Recursion.java:57:24:57:34 | readToken clls readToken | Recursion.java:57:24:57:34 | readToken clls readToken | Recursion.java:57:24:57:34 | readToken clls readToken | Found a recursion: | +| Recursion.java:57:24:57:34 | readToken clls readToken | Recursion.java:57:24:57:34 | readToken clls readToken : Token | Recursion.java:57:24:57:34 | readToken clls readToken | Found a recursion: | +| Recursion.java:71:29:71:33 | bar clls foo | Recursion.java:71:29:71:33 | bar clls foo | Recursion.java:71:29:71:33 | bar clls foo | Found a recursion: | +| Recursion.java:76:16:76:20 | foo clls bar | Recursion.java:76:16:76:20 | foo clls bar | Recursion.java:76:16:76:20 | foo clls bar | Found a recursion: | +| Recursion.java:81:16:81:32 | directRecursive clls directRecursive | Recursion.java:81:16:81:32 | directRecursive clls directRecursive | Recursion.java:81:16:81:32 | directRecursive clls directRecursive | Found a recursion: | +| Recursion.java:81:16:81:32 | directRecursive clls directRecursive | Recursion.java:81:16:81:32 | directRecursive clls directRecursive : Boolean | Recursion.java:81:16:81:32 | directRecursive clls directRecursive | Found a recursion: | +| Recursion.java:89:16:89:23 | level0 clls level1 | Recursion.java:101:16:101:23 | level2 clls level0 : Boolean | Recursion.java:89:16:89:23 | level0 clls level1 | Found a recursion: | +| Recursion.java:116:20:116:27 | level0 clls level1 | Recursion.java:128:20:128:27 | level2 clls level1 : Boolean | Recursion.java:116:20:116:27 | level0 clls level1 | Found a recursion: | +| Recursion.java:116:20:116:27 | level0 clls level1 | Recursion.java:130:16:130:23 | level2 clls level0 : Boolean | Recursion.java:116:20:116:27 | level0 clls level1 | Found a recursion: | +| Recursion.java:118:16:118:23 | level0 clls level2 | Recursion.java:118:16:118:23 | level0 clls level2 | Recursion.java:118:16:118:23 | level0 clls level2 | Found a recursion: | +| Recursion.java:124:16:124:23 | level1 clls level2 | Recursion.java:124:16:124:23 | level1 clls level2 | Recursion.java:124:16:124:23 | level1 clls level2 | Found a recursion: | +| Recursion.java:128:20:128:27 | level2 clls level1 | Recursion.java:128:20:128:27 | level2 clls level1 | Recursion.java:128:20:128:27 | level2 clls level1 | Found a recursion: | +| Recursion.java:128:20:128:27 | level2 clls level1 | Recursion.java:128:20:128:27 | level2 clls level1 : Boolean | Recursion.java:128:20:128:27 | level2 clls level1 | Found a recursion: | +| Recursion.java:128:20:128:27 | level2 clls level1 | Recursion.java:130:16:130:23 | level2 clls level0 : Boolean | Recursion.java:128:20:128:27 | level2 clls level1 | Found a recursion: | +| Recursion.java:130:16:130:23 | level2 clls level0 | Recursion.java:128:20:128:27 | level2 clls level1 : Boolean | Recursion.java:130:16:130:23 | level2 clls level0 | Found a recursion: | +| Recursion.java:130:16:130:23 | level2 clls level0 | Recursion.java:130:16:130:23 | level2 clls level0 | Recursion.java:130:16:130:23 | level2 clls level0 | Found a recursion: | +| Recursion.java:130:16:130:23 | level2 clls level0 | Recursion.java:130:16:130:23 | level2 clls level0 : Boolean | Recursion.java:130:16:130:23 | level2 clls level0 | Found a recursion: | +| Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth | Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth | Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth | Found a recursion: | +| Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth | Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth : Boolean | Recursion.java:148:16:148:54 | directRecursiveNoDepth clls directRecursiveNoDepth | Found a recursion: | diff --git a/java/test/query-tests/security/Recursion/Recursion.java b/java/test/query-tests/security/Recursion/Recursion.java index 7da173a..296d946 100644 --- a/java/test/query-tests/security/Recursion/Recursion.java +++ b/java/test/query-tests/security/Recursion/Recursion.java @@ -158,14 +158,32 @@ public boolean directRecursiveDepth(int depth) { return directRecursiveDepth(depth - 1); } - // ok: recursion is limited - public boolean directRecursiveComputedDepth(int depth) { + // todook: recursion is limited + // public boolean directRecursiveComputedDepth(int depth) { + // if (depth == 0) { + // return true; + // } + + // int newDepth = depth - 2; + // return directRecursiveComputedDepth(newDepth); + // } + + //finding: check is performed on a local variable + public boolean directRecLocalFlow(int depth) { + if (depth == 0) { + return true; + } + int newDepth = 2; + return directRecLocalFlow(newDepth - 1); + } + + // ok: recursion is limited with unary op + public boolean directRecUnaryDec(int depth) { if (depth == 0) { return true; } - int newDepth = depth - 2; - return directRecursiveComputedDepth(newDepth); + return directRecUnaryDec(depth--); } // ok: level0->level1->level2->level0 with bound @@ -184,11 +202,11 @@ public boolean level1D(int depth) { } return level2D(depth); } - public boolean level2D(int depth) { + public boolean level2D(int depth_value) { if (someCondition()) { return true; } - return level0D(depth-1); + return level0D(depth_value-1); } private boolean someCondition() {