codeql语法简介

codeql语法简介

QL Language Reference
CodeQL for 编程语言

QL的语法来自于Datalog,Datalog来源于Prolog。

参考资料:
http://www.lsv.fr/~segoufin/Papers/Mypapers/DB-chapter.pd

表达式

字符串: "abc\""

范围: [3 .. 7]

集合: [1,2,3]

this:QL可以通过class来定义类,类是结构化的逻辑表达
result: 在predict中,result用于绑定结果

super: QL中可以使用extends来表达逻辑继承

class A extends int {
  A() { this = 1 }
  int getANumber() { result = 2 }
}

class B extends int {
  B() { this = 1 }
  int getANumber() { result = 3 }
}

class C extends A, B {
  // Need to define `int getANumber()`; otherwise it would be ambiguous
  int getANumber() {
    result = B.super.getANumber()
  }
}

from C c
select c, c.getANumber()

结果:1,3

变量

变量具有类型和值。在QL中,类型是指一组值的集合,变量可以认为是该种类型下的所有值,再加上上下文中的其他限定条件,从而构成了变量的值的集合。

有限变量:变量的值有限。

无限变量:变量的值有无限个。

QL要求返回的值的集合是有限的。

变量绑定(binding):

形式是否绑定
x=1
x!=1
x+y=1y绑定,则x绑定
x > yx或y都没有绑定

Formula(规则)

exists(var decl|formula A|formula B), decl同时满足formula Aformula B
forall(var decl|formula A|formula B), 规则:forall(A | B) = not exists(A and not B)

ABnot exists(A and not B)
emptyanytrue
anyAtrue
anycontains Atrue
not emptycontains no A at allfalse
anya subset of Afalse
anycontains just a strict subset of A
i.e. A∩B is not empty
false

结论: forall(A | B) 当且仅当B是A的超集。子集 implies 超集.

forex(var decl|formula 1|formula 2), 和forall一样,但是必须保证formula 1formula 2中都至少有1个值。

  • 比如:
    forall(int i | i = 1 and i = 2 | i = 3)true,为什么?因为i = 1 and i = 2是一个空集,所以i=3一定是这个空集的超集,通常这并不是所期望的。

if-then-else:

string visibility(Class c){
  if c.isPublic()
  then result = "public"
  else result = "private"
}

A implies B : 即(not A) or B

结果是一个集合,而不是truefalse。集合的元素包括not A, 以及B中的元素。如果一个元素e ∈ A,且e ∈ A implies B, 则e ∈ B。也就是说,A implies B的所有元素,要么是不满足A的,要么是满足A且满足B的。集合的构成是排除所有满足A但不满足B的元素

例子: x%2=0 implies x%4=0, 满足x%4 = 0一定满足x%2=0。这里要排除的是那些满足A但不满足B的元素。比如3属于这个集合,但是2不属于这个集合,4属于这个集合,8也属于这个集合。
x%4=0 implies x%2=0为空,设C为满足x%4=0但不满足x%2=0的集合,x可以表达式4i,也可表达为2j+1, i,j是任意整数。从而存在i,j使4i=2j+1, 但这样的i,j并不存在,因为2(2i-j)=1,左边一定是偶数,右边是常数1。

class SmallInt extends int {
  SmallInt() { this = [1 .. 10] }
}

from SmallInt x
where x % 2 = 0 implies x % 4 = 0
select x

结果:非2的倍数(奇数),或者4的倍数
A implies B 即不满足A的,或者满足A且满足B的

递归

如果一个predict直接地,或间接地依赖自身,则它是递归的。

递归的predict必须包含至少一个基础条件,它不是递归的。QL会找到最小的那个基础条件,然后重复应用其他规则,直到结果不再变化。

下面的例子是[0,100]

int getANumber() {
  result = 0
  or
  result <= 100 and result = getANumber() + 1
}

select getANumber()

模块和库

module Example {
    class Positive extends int{
        Positive(){
             this > 0
        }
    }
}

文件,.ql(查询模块)和.qll(库模块)文件本身自动声明了一个模块,名称是文件名本身,模块体则由文件内容构成。

.ql.qll的区别:

  • 不能被引入,即import
  • 必须至少包含一条查询语句,即select

import语法:

  • import <module_name>
  • import <module_name> as <name>
  • private import <module_name>

QL首先尝试<module_name>.qll,如果找不到,则在文件自身寻找<module_name>.

import,直接引用:
<module_expression>::<name>

注意:.qll内部本身还能定义module,所以如果是嵌套的,则使用import <module_name>::<inner_module>

selectquery

.ql中可以定义selectquery来返回结果,定义query的好处是,能够被其他模块引用

query int getProduct(int x, int y) {
  x = 3 and
  y in [0 .. 2] and
  result = x * y
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值