diff --git a/java/test/query-tests/security/Recursion/Recursion.expected b/java/test/query-tests/security/Recursion/Recursion.expected index a758686..b34aa1c 100644 --- a/java/test/query-tests/security/Recursion/Recursion.expected +++ b/java/test/query-tests/security/Recursion/Recursion.expected @@ -28,6 +28,44 @@ edges | 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 | | 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 | @@ -57,6 +95,29 @@ nodes | 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 | 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: | @@ -73,3 +134,20 @@ subpaths | 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: | diff --git a/java/test/query-tests/security/Recursion/Recursion.java b/java/test/query-tests/security/Recursion/Recursion.java index f5414c9..e361b9c 100644 --- a/java/test/query-tests/security/Recursion/Recursion.java +++ b/java/test/query-tests/security/Recursion/Recursion.java @@ -172,4 +172,37 @@ public static boolean foo() { public static boolean bar() { return true; } +} + +class RecursiveCallNonLinear { + // finding: level0->...->level0 + public boolean level0() { + if (someOtherCondition()) { + return true; + } + if (someCondition()) { + return level1(); + } + return level2(); + } + public boolean level1() { + if (someCondition()) { + return true; + } + return level2(); + } + public boolean level2() { + if (someCondition()) { + return level1(); + } + return level0(); + } + + private boolean someCondition() { + return false; + } + + private boolean someOtherCondition() { + return true; + } } \ No newline at end of file