CodeQL的java库(一)

CodeQL的java库(一)

codeql的java库

CodeQL有一个用于分析从Java项目中提取分析CodeQL数据库的扩展库。这个库中的类以面向对象的形式显示数据库中的数据,并提供抽象和谓词来帮助您完成常见的分析任务。该库的实现为一组QL模块,即扩展名为.qll的文件。java.qll模块导入所有核心Java库模块,因此您可以通过以下方式开始查询codeql扫描完成的结果。

import java

本文的其余部分简要总结了这个库提供的最重要的类和动词。

注意:本文中的示例说明了不同库类返回的结果类型。这些结果本身并不有趣,但可以作为开发更复杂查询的基础。本系列文章中也介绍了如何使对一个简单的查询并对其进行微调,以方便您精确地找到您感兴趣的结果。

类摘要

标准Java库中最重要的类可以分为五大类:

1)表示程序元素的类(如类和方法)

2)表示AST节点的类(如语句和表达式)

3)用于表示元数据的类(如注释和注释)

4)计算度量的类(例如圈复杂度和耦合)

5)用于导航程序调用图的类

对于以上每一个最重要的类别,我们将对这些类别中每一个类别进行简要的描述。

表示程序元素的类

这些类表示命名的程序元素:包( Package )、编译单元( CompilationUnit )、类型( Type )、方法( Method )、构造函数( Constructor )和变量( Variable )。

它们共同的超类是 Element ,它提供了通用成员谓词,用于确定程序元素的名称并检查两个元素是否嵌套在彼此内部。

引用可能是方法或构造函数的元素通常在使用中很方便; Callable 是 Method 和 Constructor 的通用超类,可用于此目的。

类型

Type  这个类有许多子类用于表示不同类型的类型:

PrimitiveType  表示一个基本类型,即  booleanbytechardoublefloatintlongshort 之一;此外codeQL还将 void  和 <nulltype> (空文本的类型)划分为基本类型。

RefType  表示引用(即非基元)类型;它又有几个子类:

Class  表示Java类。

Interface 表示Java接口。

EnumType 表示Java枚举类型。

Array  表示Java数组类型。

例如,以下查询查找程序中所有 int  类型的变量:

import java

from Variable v, PrimitiveType pt
where pt = v.getType() and
    pt.hasName("int")
select v

引用类型也根据其声明范围进行分类:
TopLevelType  表示在编译单元的顶层声明的引用类型。
NestedType  是在另一个类型内声明的类型。
例如,此查询查找与其编译单元的名称不同的所有顶级类型:

import java

from TopLevelType tl
where tl.getName() != tl.getCompilationUnit().getName()
select tl

还有几个更细分的类:
TopLevelClass  表示在编译单元的顶层声明的类。
NestedClass  表示在另一个类型中声明的类,例如:

LocalClass ,它是在方法或构造函数中声明的类。
AnonymousClass ,它是一个匿名类。
最后,这个库还有许多封装常用Java标准库类的单例类: TypeObjectTypeCloneableTypeRuntimeTypeSerializableTypeStringTypeSystem 和TypeClass.每个CodeQL类代表由其名称所指向的标准Java类。
例如,我们可以编写一个查询来查找所有的嵌套类:

import java

from NestedClass nc
where nc.getASupertype() instanceof TypeObject
select nc

泛型

还有几个类型的子类用于处理泛型。
GenericType  可以是 GenericInterface  或  GenericClass 。它表示从Java标准库中指向一个泛型类型声明,例如  java.util.Map :

package java.util.;

public interface Map<K, V> {
    int size();

    // ...
}

类型参数(如本例中的K和V)由类 TypeVariable 表示。
泛型类型的参数化实例提供一个具体的类型来实例化类型参数,如  Map<String, File> 中所示。这样的类型由 ParameterizedType 表示,它不同于代表实例化它的泛型类型的 GenericType  。要从 ParameterizedType  转换到其对应的 GenericType ,可以使用谓词 getSourceDeclaration 。
例如,我们可以使用以下查询来查找 java.util.Map :

import java

from GenericInterface map, ParameterizedType pt
where map.hasQualifiedName("java.util", "Map") and
    pt.getSourceDeclaration() = map
select pt

一般来说,泛型类型可能会限制类型参数可以绑定到哪些类型。例如,从字符串到数字的映射类型可以声明如下:

class StringToNumMap<N extends Number> implements Map<String, N> {
    // ...
}

这意味着 StringToNumberMap  的参数化实例只能用类型 Number  或其子类型之一实例化类型参数 N  ,但不能实例化 File 。我们说N是一个有界类型参数,其上界是 Number  。在QL中,可以使用谓词 getATypeBound 查询类型变量的类型绑定。类型边界本身由 TypeBound 类表示,它有一个成员谓词 getType  来检索变量所绑定的类型。
例如,以下查询将查找类型绑定 Number 的所有类型变量:

import java

from TypeVariable tv, TypeBound tb
where tb = tv.getATypeBound() and
    tb.getType().hasQualifiedName("java.lang", "Number")
select tv

例如,在下面的代码片段中,此查询将找到 m1 ,而不是 m2 :

Map m1 = new HashMap();
Map<String, String> m2 = new HashMap<String, String>();

最后,变量可以声明为通配符类型:

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » CodeQL的java库(一)