欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

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

来源:本站整理 作者:佚名 时间:2020-02-18 TAG: 我要投稿

在前面的文章中,我们首先为读者展示了如何通过LGTM查询控制台来编写和运行分析JavaScript和TypeScript代码的查询。然后,讲解了CodeQL的JavaScript标准库中用于从文本级别和词法级别分析源代码的常用类及其谓词。在本文中,我们继续讲解CodeQL的JavaScript标准库中的其他类和谓词。
用于分析JavaScript代码的CodeQL标准库
为了帮助人们分析JavaScript代码,CodeQL平台专门提供了一个功能丰富的标准库,来帮助我们分析从JavaScript项目中提取的CodeQL数据库。这个库中的类,不仅能够以面向对象的形式表示数据库中的数据,同时,该库还提供了许多抽象类和谓词,来帮助我们完成各种常见的任务。
前面的文章介绍了用于从文本级别和词法级别分析JavaScript源代码的常用类及其谓词。接下来,我们开始讲解用于从句法层次分析JavaScript源代码的类和谓词。
语法级别
Javascript 库中的大多数类都是用于将 JavaScript 程序表示为抽象语法树(abstract syntax trees,AST)的。其中,类ASTNode不仅提供了表示抽象语法树节点的所有实体,还提供了用于遍历树节点的通用谓词:
· 谓词ASTNode.getChild(i):返回本AST节点的第i个子节点。
· 谓词ASTNode.getAChild():返回本AST节点的所有子节点。
· 谓词ASTNode.getParent():返回本AST节点的父节点(如果有的话)。
需要注意的是,这些谓词只适用于执行通用的AST遍历。若要访问特定AST节点类型的子节点,应该改用在下文中介绍的专用谓词。特别是,查询不应依赖于子节点相对于其父节点的数字索引:因为在这个库的不同版本之间,这些实现细节会随之变化。
顶层代码块
从语法的角度来看,每个JavaScript程序都由一个或多个顶层代码块(或简称顶层)组成。通常情况下,一个代码块属于另一个更大的代码块,而顶层代码块则其他JavaScript代码块。 顶层代码块可以通过类TopLevel及其子类进行表示,这些类的层级结构如下所示:
· 类Toplevel
· 类 Script:一个独立的文件或 HTML 元素
- 类ExternalScript:一个独立的 JavaScript 文件
- 类InlineScript:嵌入在 HTML 标记中的代码
· 类CodeInAttribute:源自 HTML 属性值的代码块
- 类EventHandlerCode:源自事件处理程序属性(如 onload)的代码
- 类JavaScriptURL:从带有javascript:的URL 中提取的代码
· 类Externs:包含 Externs(详情请参考https://developers.google.com/closure/compiler/docs/api-tutorial3#externs) 定义的 JavaScript 文件
TopLevel类还提供以下成员谓词:
· 谓词TopLevel.getNumberOfLines(),返回顶层代码块中代码的总行数(包括代码行、注释行和空白行)。
· 谓词TopLevel.getNumberOfLinesOfCode() ,返回代码行数,即至少包含一个单词的行数。
· 谓词TopLevel.getNumberOfLinesOfComments(),返回包含或属于注释的行数。
· 谓词TopLevel.isMinified(),根据每行的平均语句数,使用启发式方法确定顶层代码块中是否包含压缩型代码(minified code)。这里所谓的压缩,是指从源代码中删除不必要的字符,使它看起来简单而整洁。
需要注意的是,在默认的情况下,LGTM会过滤掉压缩型顶层代码块中的警报,因为它们通常难以解释。当我们在LGTM查询控制台编写自定义的查询时,这种过滤不是自动执行的,因此,如果希望执行该操作的话,可以显式一个类似and not e.getTopLevel().isMinified()的查询条件,以过滤来自压缩型代码的返回结果。
语句与表达式
除了子类TopLevel之外,类ASTNode最重要的子类就是Stmt和Expr了,通过与其他子类结合使用,这两个子类就能用于表示语句和表达式。接下来,我们为读者介绍用于表示语句与表达式的类和谓词。有关Stmt和Expr的所有子类及其API的完整资料,请参见Stmt.qll(地址为https://help.semmle.com/qldoc/javascript/semmle/javascript/Stmt.qll/module.Stmt.html)和 Expr.qll(地址为https://help.semmle.com/qldoc/javascript/semmle/javascript/Expr.qll/module.Expr.html)。
· 类Stmt:可以使用谓词ControlStmt.getAControlledStmt()来访问包含该语句的最内层函数或顶层代码块。
· 类ControlStmt:用于控制其他语句(即条件语句、循环语句、try语句或 with 语句)执行的语句;可以使用谓词ControlStmt.getAControlledStmt()来访问它控制的语句。
- 类IfStmt:用于表示一个if语句;可以使用谓词IfStmt.getCondition()、IfStmt.getThen()和IfStmt.getElse()来访问其条件表达式的“then”分支和“else”分支。
- 类LoopStmt:表示循环语句;可以使用谓词Loop.getBody()和Loop.getTest()来访问该语句的循环主体和测试表达式。
· 类WhileStmt、 DoWhileStmt:分别表示“while”循环语句和“do-while”循环语句。
· 类ForStmt:表示“for”语句;可以通过谓词ForStmt.getInit()和ForStmt.getUpdate()来访问初始条件和更新条件。
· 类EnhancedForLoop:表示“for-in”或“for-of”语句;可以通过谓词EnhancedForLoop.getIterator()来访问循环迭代器(可能是表达式或变量声明) ,并通过谓词EnhancedForLoop.getIterationDomain()来访问正在迭代的表达式。
· 类ForInStmt、 ForOfStmt:分别用于表示“for-in”和“for-of”循环语句。
· 类WithStmt:表示“with”语句;可以通过谓词WithStmt.getExpr()和WithStmt.getBody()分别访问控制表达式和 with语句的主体部分。
· 类SwitchStmt:表示“switch”语句;可以使用成员谓词SwitchStmt.getExpr()来访问“switch”语句的表达式部分;可以使用成员谓词SwitchStmt.getCase(int)和SwitchStmt.getACase()来访问单个case分支;每个case分支都可以通过类 Case的实例来表示,其成员谓词包括 Case.getExpr()和Case.getBodyStmt(int),前者可用于读取case分支中的表达式,后者用于读取case分支的主体部分。

[1] [2] [3] [4]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载