Skip to content

Commit

Permalink
java recursion simpler query
Browse files Browse the repository at this point in the history
  • Loading branch information
GrosQuildu committed Nov 15, 2024
1 parent e4e3042 commit a0e61b4
Showing 1 changed file with 16 additions and 75 deletions.
91 changes: 16 additions & 75 deletions java/src/security/Recursion/Recursion.ql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @name Recursive functions
* @id tob/java/recursion
* @description Detects recursive calls
* @id tob/java/unbounded-recursion
* @description Detects possibly unbounded recursive calls
* @kind problem
* @tags security
* @precision low
Expand All @@ -18,79 +18,20 @@ predicate isTestPackage(RefType referenceType) {
referenceType.getName().toLowerCase().matches("%test%")
}

predicate isBefore(Method a, Method b) {
a.getLocation().getStartLine() < b.getLocation().getStartLine()
}

abstract class RecursiveCall extends MethodCall {
Method m1;
Method m2;
Method m3;
Method m4;

abstract string asString();

string toString(Method m) {
result = m.getName() + "(" + m.getLocation().getStartLine() + ")" + " -> "
}
}

class RecursiveCallOrder1 extends RecursiveCall {
RecursiveCallOrder1() {
this.getMethod() = this.getEnclosingCallable() and
m1 = this.getMethod()
}

override string asString() { result = "Recursion(1): " + toString(m1) + m1.getName() }
}

class RecursiveCallOrder2 extends RecursiveCall {
//RecursiveCallOrder1 {
RecursiveCallOrder2() {
m1 = this.getMethod() and
m2 = m1.getACallee() and
m2.getACallee() = m1 and
isBefore(m1, m2)
}

override string asString() {
result = "Recursion(2): " + toString(m1) + toString(m2) + m1.getName()
class RecursiveMethod extends Method {
RecursiveMethod() {
exists(Method m | this.calls+(m) and this = m)
}
}

class RecursiveCallOrder3 extends RecursiveCall {
RecursiveCallOrder3() {
m1 = this.getMethod() and
m2 = m1.getACallee() and
m3 = m2.getACallee() and
m3.getACallee() = m1 and
isBefore(m1, m2) and
isBefore(m1, m3)
}

override string asString() {
result = "Recursion(3): " + toString(m1) + toString(m2) + toString(m3) + m1.getName()
}
}

class RecursiveCallOrder4 extends RecursiveCall {
RecursiveCallOrder4() {
m1 = this.getMethod() and
m2 = m1.getACallee() and
m3 = m2.getACallee() and
m4 = m3.getACallee() and
m4.getACallee() = m1 and
isBefore(m1, m2) and
isBefore(m1, m3) and
isBefore(m1, m4)
}

override string asString() {
result =
"Recursion(4): " + toString(m1) + toString(m2) + toString(m3) + toString(m4) + m1.getName()
}
}

from RecursiveCall recursiveCall
where not isTestPackage(recursiveCall.getMethod().getDeclaringType())
select recursiveCall, "$@", recursiveCall, recursiveCall.asString()
/**
* TODO ideas:
* - limit results to methods that take any user input
* - check if recursive calls are bounded (takes argument that is decremented for every call)
* - do not return methods that have calls to self (or unbounded recursion) that are conditional
* - gather and print whole call graph (list of calls from recursiveMethod to itself)
*/
from RecursiveMethod recursiveMethod
where
not isTestPackage(recursiveMethod.getDeclaringType())
select recursiveMethod, "Method $@ has unbounded, possibly infinite recursive calls", recursiveMethod, recursiveMethod.toString()

0 comments on commit a0e61b4

Please sign in to comment.