如果你在一个类里没有找到某个谓词,那么你就应该去父类中去找一找。
下面是 CodeQL 中的类的继承图,然后我按照层级给各个类分一下层级,方便查询
Java 库函数
第一层
Top
from Top top
top.getAPrimaryQlClass()获取当前 top 的最直接的 QL 类(通常用于判断表达式、语句等的类型)。返回 string
第二层
Element
from Element element
element.hasName(string name)判断 element 的名称是否为 name。无返回值。element.getName()获取 element 的名称。返回 string。element.fromSource()判断 element 是否来自于源代码文件。无返回值。
第三层
Call
from Call call
call.getCallee()获取 call 过程中被调用的 callable 是谁(例如函数调用中被调用的函数是谁)。返回 Callable。call.getCaller()获取 call 表达式被哪个函数包裹(如果我们对一个函数1的函数体里的 call 表达式使用这个 getCaller() 函数,那么返回的就是这个函数1)。返回 Callable。
Expr
from Expr expr
expr.getType()获取当前表达式的类型。返回 Type。expr.getIndex()获取当前表达式在其父表达式中排第几位。返回 int。expr.getEnclosingCallable()获取当前表达式被哪个 callable 所包裹。返回 Callable。
Stmt
from Stmt stmt
stmt.getAChild()获取语句的子语句(比如 if 语句的 {} 里面的语句。)。返回 Stmt。
第四层
Member
from Member member
member.getDeclaringType()获取定义member的类, 也就是那个类里有这个 member。返回RefType
RefType
就是引用类型,这里通常是指一个类。
from RefType reftype
reftype.hasQualifiedName(string package, string type)判断一个引用类型的全限定名是否为package.type。无返回值reftype.getAField()获取 reftype 的属性。返回 Field。reftype.getAMethod()获取 reftype 的所有方法。返回 Method。reftype.getPackage()获取 reftype 所属于哪个包。返回 Package。reftype.getASupertype()获取 reftype 的直接超类型。返回 Reftype。reftype.getASubtype()获取 reftype 的直接子类型。返回 Reftype。reftype.getAMember()获取 reftype 内部定义的成员,例如函数、字段等。返回 Member。reftype.inherits(Member m)判断 reftype 内部是否定义或继承有 m。无返回值。reftype.reftype.reftype.reftype.
MethodCall
from MethodCall methodcall
methodcall.getEnclosingCallable()获取该 methodcall 被哪个 callable 包裹的(就是当前的方法调用语句写在哪个函数的方法体里)。返回 Callable。methodcall.getAnArgument()获取该 methodcall 传入的所有参数。返回 Expr。methodcall.getArgument(int index)获取当前 methdocall 所传入的第 index 的参数。返回 Expr。methodcall.getEnclosingStmt()获取当前 methdocall 被哪个语句所包裹。返回 Stmt。methodcall.getAChildExpr()获取 methodcall 表达式的子表达式(获取调用者和参数)。返回 Expr。例如:
userComments.remove(user);会返回userComments和user。
ArrayCreationExpr
from ArrayCreationExpr ace
ace.getFirstDimensionSize()获取当前的 数组创建表达式 的第一个维度是几维。返回 int。
BlockStmt
from BlockStmt blockstmt
blockstmt.getNumStmt()获取 blockstmt 内共有多少条语句。返回 int。
第五层
Field
from Field field
field.getType()获取 field 的类型。返回 Type。field.getDeclaration()获取定义 field 的类。返回 FieldDeclaration。
Callable
from Callable callable
callable.getAParameter()获取该 callable 的所有参数。返回 Parameter。callable.getACallee()获取该 callable 方法体内所调用的其他所有 callable(说白了就是看一个函数里调用哪些其他函数)。返回 Callable。callable.calls(Callable target)判断 callable 是否使用了 target。无返回值。callable.polyCalls(Callable target)判断 callable 实际真正调用的最终函数会不会是 target 呢?无返回值
Super s = new Sub(42); s.getX();比如这句代码,我们明面上调用的是 Super.getX() 实际真正上调用的是 Sub.getX()。
IfStmt
from IfStmt ifstmt
ifstmt.getElse()获取 ifstmt 的 else 语句部分。返回 Stmt。ifstmt.getCondition()获取 ifstmt 语句中的 条件表达式语句语句。返回 Expr。
第六层
Class
from Calss class
class.getAnAnnotation()获取 class 的所有注解。返回 Annotation。class.isAnonymous()判断 class 是不是匿名类。无返回值。
Method
from Method method
method.overrides(Method m)判断 method 是否是覆写了 方法m。无返回值。method.getASourceOverriddenMethod()获取 method 所覆写的原始函数。返回 SrcMethod。method.getSignature()获取 method 的签名。返回 string。method.getAReference()获取对该 method 的调用或者说使用。返回 MethodCall。
CodeQL 语言基础函数
string
string.indexof(string s)返回 s 在 string 中的位置,从 0 开始。返回 int
特殊:假如说现在有一个代码:
.param("field1", "abcd")其中"field1"是一个表达式,设为 e1,然后执行 e1.toString().indexOf("f") 结果是 1, 因为 0 位置的是"。
DataFlow 数据流分析函数
DataFlow::localFlow(Node node1, Node node2)判断 node1 到 node2 是否为有效本地数据流, 经过 0 个或者多个步骤均可, 0 步骤不是代表没有流经,而是代表 node1 流向 node1 自身这叫经过 0 个步骤。DataFlow::localFlowStep(Node node1, Node node2)判断 node1 到 node2 是否为有效本地数据流,并且只经过 1 个步骤。
TaintTracking::localTaint(Node node1, Node node2)判断 node1 到 node2 是否为有效的污点数据流,经过 0 个或者多个步骤均可。TaintTracking::localTaintStep(Node node1, Node node2)判断 node1 到 node2 是否为有效的污点数据流并且只经过 1 个步骤。
DataFlow::parameterNode(Parameter p)获取 p 对应的 参数节点。返回 ExplicitParameterNode。DataFlow::exprNode(Expr e)获取 e 对应的 表达式节点,返回 ExprNode。
第一层
第二层
DataFlow::Configuration
conf.hasFlow(Node source, Node sink)判断 source 到 sink 之间是否有全局数据流。
conf.isSource(Node source)自行实现方法体。判断 source 是否为 source。无返回值。conf.isSink(Node sink)自行实现方法体。判断 sink 是否为 sink。无返回值。conf.isAdditionalFlowStep(Node node1, Node node2)自行实现方法体。强制将一个 节点 传递给另一个节点。无返回值。
x = "危险数据" y = someFunction(x) eval(y)暂时还没有理解这个函数。
conf.isSanitizer(Node node)自行实现方法体。判断 node 是否应该被截止。无返回值。