https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-java/
https://codeql.github.com/codeql-standard-libraries/java/
一、五大类库
Program Elements,程序元素,例如类和方法
AST nodes 抽象树节点,例如语句和表达式
Metadata 元数据,例如注解和注释
metrics,计算指标,例如循环复杂度
Call Gragh,调用图
二、程序元素
顶级类 Element
程序元素包含:packages (Package), compilation units (CompilationUnit), types (Type), methods (Method), constructors (Constructor), and variables (Variable).
点击查看【processon】
1、类型,TODO
顶级类 Type
PrimitiveType 主数据类型
boolean, byte, char, double, float, int, long, short, void,
, null
RefType 引用类型
Class、Interface、EnumType、Array
查询示例:查询所有int类型的变量
import java
from Variable v, PrimitiveType pt
where pt = v.getType() and
pt.hasName("int")
select v
TopLevelType
NestedType
TopLevelClass
NestedClass
2、泛型,TODO
顶级类 Type
GenericType
GenericInterface
GenericClass
TypeVariable
代码示例:查找所有java.util.Map的参数实例
import java
from GenericInterface map, ParameterizedType pt
where map.hasQualifiedName("java.util", "Map") and
pt.getSourceDeclaration() = map
select pt
3、变量
顶级类 Variable
Field,Java字段
LocalVariableDecl,局部变量
Parameter,方法参数、构造器参数
三、抽象语法树
两个顶级类
Stmt,Statements语句
Expr,Expressions表达式
遍历AST
Expr.getAChildExpr
returns a sub-expression of a given expression.
Stmt.getAChild
returns a statement or expression that is nested directly inside a given statement.
Expr.getParent
Stmt.getParent
return the parent node of an AST node.
AST内容详细内容可见第10章节:Java抽象语法树
查询示例1:查询return语句内嵌套的表达式
当样本是return 1+1时,将会匹配 1+1
import java
from Expr e
where e.getParent() instanceof ReturnStmt
select e
查询示例2:查询if语句内内嵌套的表达式
import java
from Stmt s
where s.getParent() instanceof IfStmt
select s
匹配结果示例,样本来源WebGoat
查询示例3:查询方法内的语句
import java
from Stmt s
where s.getParent() instanceof Method
select s
匹配结果示例,样本来源WebGoat
四、元数据
注解顶级类:Annotatable
包括包、引用类型、字段、方法、构造器和局部变量声明,可以通过程序元素的谓词getAnAnnotation来获取。
代码示例:查询类构造器的注解
import java
from Constructor c
select c.getAnAnnotation()
匹配结果示例,c.getAnAnnotation()的值是Inject
代码示例:查询已经废弃的构造方法
import java
from Constructor c, Annotation ann, AnnotationType anntp
where ann = c.getAnAnnotation() and
anntp = ann.getType() and
anntp.hasQualifiedName("java.lang", "Deprecated")
select ann
文档顶级类,Javadoc
程序元素可以使用谓词getDoc来获取Document对象
代码示例:获取私有字段的Java文档注释
import java
from Field f, Javadoc jdoc
where f.isPrivate() and
jdoc = f.getDoc().getJavadoc()
select jdoc
匹配结果示例
代码示例:查询私有变量文档注释内部任意深度的作者标签
import java
from Field f, Javadoc jdoc, AuthorTag at
where f.isPrivate() and
jdoc = f.getDoc().getJavadoc() and
at.getParent+() = jdoc
select at
五、指标,TODO
MetricElement,MetricPackage,MetricRefType,MetricField,MetricCallable,和MetricStmt
程序元素可以使用谓词getMetrics来获取指标对象
代码示例:查询循环复杂度大于40的方法
import java
from Method m, MetricCallable mc
where mc = m.getMetrics() and
mc.getCyclomaticComplexity() > 40
select m
六、调用关系
顶级类Callable
可以使用Call.getCallee查询表达式所引用的方法或者构造器。(Call继承自Expr)
代码示例:查询所有名为println的调用方法
import java
from Call c, Method m
where c.getCallee() = m and
m.hasName("println")
select c
匹配结果示例
代码示例:查询未被引用过的调用
import java
from Callable c
where not exists(c.getAReference())
select c