From 23234fba2b48c41b09ca1a6cd80ef9c795e4c12b Mon Sep 17 00:00:00 2001 From: yancang Date: Mon, 29 Jul 2024 11:55:44 +0800 Subject: [PATCH 1/2] give example: given a method signature a, we want to find out which methods call a. We keep searching until we find the top method, and output all the links from the top method to a. --- example/java/CallChainWithSignature.gdl | 89 +++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 example/java/CallChainWithSignature.gdl diff --git a/example/java/CallChainWithSignature.gdl b/example/java/CallChainWithSignature.gdl new file mode 100644 index 00000000..ae7e2dcc --- /dev/null +++ b/example/java/CallChainWithSignature.gdl @@ -0,0 +1,89 @@ +// script +use coref::java::* + +fn default_java_db() -> JavaDB { + return JavaDB::load("coref_java_src.db") +} + +// Given one or more function signatures, only one is given in the current example, which can be modified +// signature +fn isChecked(signature: string) -> bool { + [ + {"HelloWorld.test2:void()"}, + ] +} + +// You can view the signature, line number, and file location of each callable by outputting the following function: +fn signature_name(signature: string, line: int, fileName: string) -> bool { + let (db = default_java_db()){ + for (callable in Callable(db)){ + if (signature = callable.getSignature() && fileName = callable.getLocation().getFile().getName() + && line = callable.getLocation().getStartLineNumber()) { + return true + } + } + } +} + +// Determine whether it is a callable corresponding to the function signature +fn checkCallable(c: Callable)-> bool { + if (isChecked(c.getSignature())) { + return true + } +} + + +// Do an upward search +// Search upwards for the end condition, and restrict some properties of the end node +fn callerLimit(c: Callable) -> bool { + return false +} +fn getAncestorCallerEndWithLimit(c: Callable) -> *Callable { + // If the current function has been limited + if (callerLimit(c)) { + yield c + } + if (!callerLimit(c)) { + // Get the calling function of the current functio + yield c.getCaller() + // The current node is multiple layers above, and recursive calls are required to obtain all calling functions + for (tmp in c.getCaller()) { + yield getAncestorCallerEndWithLimit(tmp) + } + } +} + +fn getAllLimitedCallable(c:Callable)->*Callable{ + yield c + yield getAncestorCallerEndWithLimit(c) +} + +// At the same time, output the class corresponding to callable +fn getCallGraph(callMethodName:string, callClassName: string, + calleeMethodName:string, calleeClassName: string) -> bool { + let (db = default_java_db()){ + for (callable in Callable(db)){ + if (checkCallable(callable)) { + for (call in getAllLimitedCallable(callable), callee in getAllLimitedCallable(callable)){ + if (call != callee && callee in call.getCallee()) { + for (callMethod in Method(db), calleeMethod in Method(db)) { + if (callMethod.key_eq(call) && calleeMethod.key_eq(callee)) { + if (callMethodName = callMethod.getName() && callClassName = callMethod.getBelongedClass().getQualifiedName() && + calleeMethodName = callee.getName() && calleeClassName = calleeMethod.getBelongedClass().getQualifiedName()) { + return true + } + } + } + } + } + } + + } + } +} + +fn main() { + output(getCallGraph()) + // If you want to see the signature in the output add the following line back + // output(signature_name()) +} \ No newline at end of file From f935ce540c06ec6947653b2c84b775503ef657d8 Mon Sep 17 00:00:00 2001 From: yancang Date: Mon, 29 Jul 2024 14:15:02 +0800 Subject: [PATCH 2/2] Modify the script writing method to pass CI detection --- example/java/CallChainWithSignature.gdl | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/example/java/CallChainWithSignature.gdl b/example/java/CallChainWithSignature.gdl index ae7e2dcc..1a03db36 100644 --- a/example/java/CallChainWithSignature.gdl +++ b/example/java/CallChainWithSignature.gdl @@ -34,22 +34,12 @@ fn checkCallable(c: Callable)-> bool { // Do an upward search -// Search upwards for the end condition, and restrict some properties of the end node -fn callerLimit(c: Callable) -> bool { - return false -} fn getAncestorCallerEndWithLimit(c: Callable) -> *Callable { - // If the current function has been limited - if (callerLimit(c)) { - yield c - } - if (!callerLimit(c)) { - // Get the calling function of the current functio - yield c.getCaller() - // The current node is multiple layers above, and recursive calls are required to obtain all calling functions - for (tmp in c.getCaller()) { - yield getAncestorCallerEndWithLimit(tmp) - } + // Get the calling function of the current functio + yield c.getCaller() + // The current node is multiple layers above, and recursive calls are required to obtain all calling functions + for (tmp in c.getCaller()) { + yield getAncestorCallerEndWithLimit(tmp) } }