代码分析平台CodeQL学习手记(二) - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

代码分析平台CodeQL学习手记(二)

fanyeee 技术 2019-12-24 11:26:53
1294557
收藏

导语:在本文中,我们开始为读者介绍QL编程语言中的基本数据类型,以便为将来的代码分析工作打好基础。

代码分析平台CodeQL入门(一)

在上一篇文章中,我们为读者介绍了CodeQL平台相关的基本概念,并演示了如何编写和运行简单的QL程序。在本文中,我们开始为读者介绍一些简单的数据类型,以便为将来的编程工作打好基础。

基本数据类型及其内建函数

现在,我们开始学习QL语言中的基本数据类型,包括整型、浮点型、日期型、布尔型以及字符串类型。需要注意的是,对于QL语言来说,其支持的数据类型都带有相应的内建函数——通俗来说,就是系统已经为我们写好的函数,我们直接拿来就能用了。举例来说,如果我们想求一个整数的绝对值,直接调用内建函数abs()即可,例如-6.abs()。更一般地说,调用某种类型的变量的通用形式为:直接在变量后面加上一个点号,然后加上要调用的内建函数即可。同时,我们还可以通过点号将多个函数串联起来,也就是对变量连续进行多种处理,例如,对于一个整型变量a,先求绝对值,再开平方,我们可以将这个处理过程表示为:a.abs().sqrt()。

读者可能已经发现,在查询控制台中,当我们在变量后面输入点号之后,会自动弹出一个含有该类型的变量所有可能的函数列表,这时,我们可以通过鼠标点选所需的函数,具体如下所示:

1.png

另外,当查询控制台检测到潜在的语法错误后,它会在代码行号左边显示一个红色的“x”号,或者在相应的字符下面显示红色的波浪线。例如,当我们给一个字符串变量赋予一个整数值,并调用绝对值和开平方的函数时,查询控制台就会给出相应的提示:

2.png

字符串类型

字符串类型的变量用来存放以双引号开头和结尾的字符序列,即字符串。例如:

from string s
where s = "hello"
select s

其中,在from语句中,我们定义了一个字符串类型的变量s,然后,我们在where语句中,将字符串”hello”赋值给了变量s,最后,我们在select语句中返回变量s的值。如果在查询控制台运行上述代码的话,运行结果将为:

hello

注意,上面的运行结果中,并没有出现双引号。这是因为,双引号是一个特殊字符:字符串通常使用双引号"..."来表示开始和结束,所以双引号本身不会显示出来。读到这里,读者可能会问:如果字符串本身恰好包含一个"字符的话,那该怎么表示呢?这个时候,就该转义字符\上场了。具体来说,只要在双引号前面加上一个反斜杠,双引号就不再表示字符串的开始或结束位置的指示符,而是表示双引号自身了,具体如下所示:

from string s
where s = "he\"llo"
select s

现在,上述代码的运行结果会变为:

he"llo

您可能还会问:如果要显示表示转义字符的反斜杠的话,该怎么办呢?很简单,只要在反斜杠的前面再加上一个反斜杠就行了。下面列出的是常见的转义字符:

n  \" 表示字符"
n  \\ 表示字符\
n  \n 表示换行符
n  \r 表示回车符
n  \t 表示制表符

同时,QL语言还为字符串类型提供了许多内置的函数,按照官方的说法,就是内置谓词,例如charAt()函数,该函数可以接收一个表示字符串下标的整型参数,并返回指定下标处的字符。准确来说,该函数的返回值的类型仍然是字符串类型,只不过只包含单个字符而已。请看下面的示例代码:

from string s
where s = "hello"
select s.charAt(0)

上述代码的运行结果为:

h

从上面的结果可以看出,字符串元素的下标是从0开始算起的。此外,字符串类型内置的函数有二十多个,这里就不一一介绍了,具体可以访问QL的语言规范(https://help.semmle.com/QL/ql-spec/language.html#built-ins-for-string)。

整型与浮点型

简单来说,整型变量用于保存整数,如306;而浮点型变量则用于保存浮点数,也就是带小数位的数,如3.14。例如:

 from float x, int y
 where x = 3.6 and y = 3
 select x.pow(y)

就本例来说,上述代码实际上就是计算3.6的3次方,运行结果为:

46.656000000000006

同样的,整型和浮点型也内建了许多函数,例如,abs()函数等,并且,它们的大部分函数的名称和作用都是相同的,感兴趣的读者可以参阅QL的语言规范(https://help.semmle.com/QL/ql-spec/language.html#built-ins-for-string)。

日期型

日期型变量用于保存公历表示的时间值和日期值,如年、月、日、时、分、秒以及毫秒等,注意,它们的取值都是整数。其中,表示年的整数的取值范围是从-16777216到16777215,表示月的整数的取值范围为从0到11,表示日的整数的取值范围是从1到31,表示时的整数的取值范围是从0到23,表示分的整数的取值范围是从0到59,表示秒的整数的取值范围是从0到59,表示毫秒的整数的取值范围是从0到999。

下面,我们编写一个查询,来计算从今年十月一到2019年12月18日为止已经过去了多少天了,具体如下图所示:

3.png

运行结果如下所示:

4.png

 

需要注意的是,上面代码中的"01/10/2019"是一个字符串,而函数toDate()是字符串类型的内置函数,其作用是将指定的字符串转换为日期值。同样的,日期型也提供了许多内置的函数,如getMonth()函数可以用来提取日期值中的月份部分,具体如下所示:

5.png

运行上述代码后,提取到的月份如下所示:

6.png

对于日期型数据来说,除了上面介绍的daysTo()和getMonth()函数外,还有多种函数可以供我们使用,感兴趣的读者可以参阅QL的语言规范(https://help.semmle.com/QL/ql-spec/language.html#built-ins-for-string)。

布尔型

布尔型变量用来存放布尔值,即false(假)或者 true(真)。为了便于读者理解,这里举例说明:

from boolean b
where b = false
select b.booleanNot()

在上面的代码中,我们定义了一个布尔型变量b,并将其赋值为false,最后返回对变量b进行逻辑非操作后的值。上述代码的运行结果为:

true

其中,上面的函数booleanNot()的作用,是执行逻辑非运算,也就是取反:真变假,假变真。这里逻辑变量b原来的值为假(false),取反后,自然就变成真(true)了。接下来,我们再来看看booleanAnd()函数,它能够用来实现一个逻辑值与另一个(通过参数传入的)逻辑值的逻辑与运算:

from boolean b
where b = false
select b.booleanAnd(true)

上述代码的运行结果为:

false

这是因为,只有当两个逻辑值都为真时,其逻辑与运算的结果才为真。下面,我们再来看看用于实现逻辑或运算的函数,即booleanOr()。下面,我们举例说明:

from boolean b
where b = false
select b.booleanOr(true)

与上面的函数相似,它也需要传入一个逻辑值或表达式作为其参数。上述代码的运行结果为:

true

对于逻辑或运算来说,只要参加运算的值中有一个为真,那么,其结果就为真。接下来,我们继续考察用来实现异或运算的函数,即booleanXor()函数,演示代码如下所示:

from boolean b
where b = false
select b.booleanXor(true)

上述示例代码的运行结果为:

true

这是因为,对于异或运算来说,只要两个逻辑值不相等,其结果就为真;否则,其结果为假。最后,我们来看一下将逻辑值转换为字符串的函数:toString()函数,具体代码如下所示:

7.png

运行结果如下所示:

8.png

尽管字面上看,与逻辑值中的假值即false是一样的,但是,实际上它们是完全不同的两种数据类型——这里输出的值是一个字符串。

小结

在上一篇文章中,我们为读者介绍了CodeQL平台相关的基本概念,并演示了如何编写和运行简单的QL程序。在本文中,我们进一步为读者介绍了一些基本的数据类型。在下一篇文章中,我们将为读者详细与代码分析紧密相关的一些数据类型。

备注:本系列文章乃本人在学习CodeQL平台过程中所做的笔记,希望能够对大家有点滴帮助——若果真如此的话,本人将备感荣幸。

参考资料:https://help.semmle.com/

  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务