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

fanyeee 嘶吼专业版

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

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

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

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

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

字符串类型

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

from string swhere s = "hello"select s

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

hello

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

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

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

he"llo

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

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

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

from string swhere 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日为止已经过去了多少天了,具体如下图所示:

运行结果如下所示:

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


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

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

布尔型

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

from boolean bwhere b = falseselect b.booleanNot()

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

true

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

from boolean bwhere b = falseselect b.booleanAnd(true)

上述代码的运行结果为:

false

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

from boolean bwhere b = falseselect b.booleanOr(true)

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

true

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

from boolean bwhere b = falseselect b.booleanXor(true)

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

true

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

运行结果如下所示:

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

小结

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

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

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

©著作权归作者所有:来自51CTO博客作者mob604756ebed9f的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 无需手工设计,从零开始搜索损失函数
  2. 在Oracle中,如何判断一个字符串是否为数字?
  3. MySQL 隐式类型转换
  4. oracle Extract 函数
  5. Linux系统下对文件和字符串 进行加密的方法总结
  6. Oracle中CAST函数使用简介
  7. python实战系列之python变量
  8. Python3入门视频教程百度网盘
  9. 聊一聊toString和valueOf

随机推荐

  1. Xamarin Mono Android实现“再按一次退出
  2. 一起学android之EditText的各种使用(15)
  3. Android -- 设置textview文字居中或者控
  4. 在Android模拟器安装应用
  5. Android开发常用代码片段(三)
  6. Kotlin Anko Layout+MVP(Glide,Retrofit,
  7. APIDEMO GRIDVIEW
  8. Android(安卓)读取内存文件返回byte数组
  9. #AndroidDevSummit,就在此刻!
  10. Android TextView多行文本滚动实现