Complex Steps are CPGQL Steps which combine the functionality of one or more Node-Type Steps, Repeat Steps, Filter Steps, Core Steps or Execution Directives. They are represented by one or more Directives and can be of three types: Generic Complex Steps, Call Graph Steps or Dataflow Complex Steps.
Generic Complex Steps #
dump #
dump
is a Complex Step which executes the traversal and returns the value of the CODE property of the nodes it suffixes with syntax-highlighting.
joern> cpg.method.name("main").dump
res0: List[String] = List(
"""int main(int argc, char *argv[]) { /* <=== */
if (argc > 1 && strcmp(argv[1], "42") == 0) {
fprintf(stderr, "It depends!\n");
exit(42);
}
printf("What is the meaning of life?\n");
exit(0);
}"""
)
dumpRaw #
dumpRaw
is a Complex Step which executes the traversal and returns the value of the CODE property of the nodes it suffixes.
joern> cpg.method.name("main").dumpRaw
res0: List[String] = List(
"""int main(int argc, char *argv[]) { /* <=== */
if (argc > 1 && strcmp(argv[1], "42") == 0) {
fprintf(stderr, "It depends!\n");
exit(42);
}
printf("What is the meaning of life?\n");
exit(0);
}"""
)
tagList #
tagList
is a Complex Step which executes the traversal and returns the list of all TAG nodes found at each node visited by the traversal it suffixes.
joern> cpg.method.tagList
res0: List[List[TagBase]] = List(List(NewTag("MY_TAG", "")))
Call Graph Steps #
Call Graph Steps are Complex Steps which traverse the nodes of a Code Property Graph which represent a program’s Call Graph.
The following examples are run on the simple program named X42
:
public class X42 {
public static void main(String[] args) {
if (args.length > 0 && args[0].equals("42")) {
System.err.println("It depends!");
System.exit(42);
}
System.out.println("What is the meaning of life?");
System.exit(0);
}
}
callee #
callee
is a Call Graph Step which lists all nodes representing Call Graph callees of the traversed nodes.
joern> cpg.method.name("main").callee.name.l
res0: List[String] = List(
"printf",
"exit",
"exit",
"<operator>.logicalAnd",
"<operator>.greaterThan",
"<operator>.equals",
"fprintf",
"strcmp",
"<operator>.indirectIndexAccess"
)
caller #
caller
is a Call Graph Step which lists all nodes representing Call Graph callers of the traversed nodes.
joern> cpg.method.name("exit").caller.code.l
res0: List[String] = List("main (int argc,char *argv[])", "main (int argc,char *argv[])")
callIn #
callIn
is a Call Graph Step which lists all nodes representing Call Graph parent call-sites of the traversed nodes.
joern> cpg.method.name("exit").callIn.code.l
res0: List[String] = List("exit(0)", "exit(42)")
inCall #
inCall
is a Call Graph Step which lists all nodes representing surrounding Call Graph call-sites of the traversed nodes.
joern> cpg.call.name("<operator>.indirectIndexAccess").inCall.code.l
res0: List[String] = List("strcmp(argv[1], \"42\")")
Dataflow Steps #
Dataflow Steps are Complex Steps which traverse the nodes of a Code Property Graph which represent a program’s data-flow. controlledBy
, flows
, source
, sink
, reachableBy
are all CPGQL Components that are combined to construct Dataflow Steps.