joern > config.tools.imageViewer = "/path/to/a/different/viewer"
cpg.method.isExternal
int i;
int buf[N];
for(i = 0; i <= N; i++){
buf[i] = 1;
}
buf[i]= 0;
joern> cpg.method.controlStructure.expressionDown.order(2).code.l
res45: List[String] = List("i <= N")
joern> val loopTo = cpg.method.controlStructure.expressionDown.order(2).isCallTo(Operators.lessEqualsThan).argument.order(2).code.l.head
loopTo: String = "N"
joern> cpg.method.local.typeFullNameExact(s"""int [ $loopTo ]""").code.l
res60: List[String] = List("buf")
cpg.method // query all methods
.controlStructure // filter for control structures
.parserTypeName("ForStatement") // only for statements
.expressionDown // "going one layer down"
.order(2) // choosing the second argument of the expression => for(i = 0; i <= N; i++){
.isCallTo(Operators.lessEqualsThan) // it has to be a call to "<="
.argument // going to the arguments of the call to "<="
.order(2) // second argument is the "N"
.code // get the code of the second argument
.l // as list (in this case it is only argument but could be more)
.head // get the first entry in the list
x42-c
for code at ./x42/c
hey @FJuilia_twitter! Joern features a step named ddgIn
you can use to follow data dependency edges. For example, in the following program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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);
}
you can follow DDG edges for the call to strcmp like so:
joern> cpg.call.name("strcmp").ddgIn.l
res103: List[nodes.TrackingPoint] = List(
Literal(
id -> 1000117L,
code -> "0",
order -> 2,
argumentIndex -> 2,
typeFullName -> "int",
dynamicTypeHintFullName -> List(),
lineNumber -> Some(6),
columnNumber -> Some(43),
depthFirstOrder -> None,
internalFlags -> None
),
MethodParameterIn(
id -> 1000104L,
code -> "char *argv[]",
order -> 2,
name -> "argv",
evaluationStrategy -> "BY_VALUE",
typeFullName -> "char * [ ]",
dynamicTypeHintFullName -> List(),
lineNumber -> Some(5),
columnNumber -> Some(19)
)
)
reachableBy
might also help:joern> cpg.call.name("strcmp").reachableBy(cpg.method.parameter).l
res105: List[MethodParameterIn] = List(
MethodParameterIn(
id -> 1000104L,
code -> "char *argv[]",
order -> 2,
name -> "argv",
evaluationStrategy -> "BY_VALUE",
typeFullName -> "char * [ ]",
dynamicTypeHintFullName -> List(),
lineNumber -> Some(5),
columnNumber -> Some(19)
)
)