【Lua篇】静态代码扫描分析(四)规则检查
一、前言
通过前面三篇文章已经初步实现了将Lua源代码文件读取解析成语法树,现在就可以通过得到的语法树进行指定规则的代码扫描检查。下图简单列举了一下单个Lua文件内部的语法关系情况(注意并非真正的类图,也没有列举完全部的节点类型)。

二、变量作用域
1 function main()
2 local value = g_total + 1
3 print("value:", value)
4 end
上面的简单代码里有一个g_total的全局变量,它可能来自前面代码块的定义,也有可能来自底层导出的符号,或者是在其他文件中定义的全局变量。因此在判断一个变量是否存在首先需要创建一个全局的变量列表或白名单列表。
1 function demo(params)
2 local value1 = 1
3 if value1 == params then
4 local var_b = 2
5 local var_c = var_b + value1
6 end
7 end
上面代码也是一个函数声明,它有自己的私有变量列表(包括参数params和内部的变量value1);而var_b、var_c则属于是if内部的私有变量列表,在if之外是无法访问的。因此在代码扫描之前需要先建立不同参数的作用域。
先对所有文件的语法树扫描一遍,把里面的所有变量都记录下来,存入全局变量列表、当前文件变量列表、或者某个内部代码块的变量列表。然后再才对单个文件进行规则扫描。特别需要注意module方法声明的模块,内部的不加local的变量属于module的公共变量。
1 def build_symbols(block):
2 # block参数就是当前文件的全部代码
3 for statement in block.statements:
4 # 变量声明,属于block的自私变量列表
5 if statement.nodeType == LNodeCode.IDENTIFIER:
6 # 赋值包括a=1 和 a,b =1,2 等复杂的赋值语句
7 # 没有加local的情况下,很可能是全局变量
8 elif statement.nodeType == LNodeCode.ASSIGNMENT:
9 # 函数定义,需要检查函数体内部的语句statement.block
10 # 递归调用build_symbols检查
11 elif statement.nodeType == LNodeCode.FUNC:
12 # 函数调用类似 module("test",seeall)模块声明, 全局的test
13 # 类似 CreateClass("A", superB) ,全局的A
14 elif statemen
三、规则扫描
根据需要进行的一系列的规则进行语法树扫描检查,以检查变量是否存在为例:
1. 检查变量时需要先在局部变量列表中查找(if、for等代码块;函数代码块;文件代码块等)
2. 没有找到再去模块的公共变量列表(module)
3. 最后去全局变量列表中查找
4. 如果都没有找到的话那么就很可能这个变量不存在。
1 if statement.nodeType == LNodeCode.IDENTIFIER:
2 # 单个变量的声明只有可能是local a
3 check_var(statement.name, statement.is_local)
4 elif statement.nodeType == LNodeCode.FUNC_CALL:
5 # 函数调用的参数检查
6 check_multi_vars(statement.args)
7 # 函数本身检查,看是否有这样的函数
8 check_func(statement.name)
9 elif statement.nodeType == LNodeCode.OP:
10 # 操作例如+-*/%等,需要检查左右的操作变量是不是存在
11 check_left_vars(statement.left)
12 check_right_vars(statement.right)
同样也是遍历文件的block、函数体block、各种语句的block进行变量的存在性检查,具体的内部检查由于代码篇幅太长,就不详细贴出来了。
Lua静态代码扫描的基本处理方法就算列举完了,实际项目的代码中会比较复杂,而且扫描的规则也会有很多不同的需求,就需要实际去做才理解了。
文章来自我的公众号,大家如果有兴趣可以关注,具体扫描关注下图。

【Lua篇】静态代码扫描分析(四)规则检查的更多相关文章
- 【Lua篇】静态代码扫描分析(一)初步介绍
一.静态代码分析 静态代码分析是一种通过检查代码而不是执行程序来发现源代码中错误的手段.通常可以帮助我们发现常见的编码错误,例如: 语法错误 违反制定的标准编码 未定义的变量 安全性问 ...
- 【Lua篇】静态代码扫描分析(三)语法分析
一.语法分析 通过将词法分析获取的Token流按照目标语言的语法进行解析的过程,例如解析函数声明.函数调用.变量声明.各种语句等. 二.Lua语法分析 在写语法分析程序前,先需要了解Lua的语句和语法 ...
- 【Lua篇】静态代码扫描分析(二)词法分析
一.词法分析 词法分析(英语:lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程.进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer, ...
- 静态代码扫描工具PMD定制xml的规则(一)操作篇
0.前言 PMD作为开源的静态代码扫描工具有很强的扩展能力,可使用java或xpath定制rule.第一篇从操作上讲解如何定制一个用于扫描xml是否规范的规则.首先我们知道xml格式的文件在java工 ...
- DEVOPS技术实践_05:sonar静态代码扫描
一.SonarQube静态代码扫描平台 1.1 安装 https://www.sonarqube.org/官网 1.2 下载软件包 https://www.sonarqube.org/download ...
- 使用OClint进行iOS项目的静态代码扫描
使用OClint进行iOS项目的静态代码扫描 原文链接:http://blog.yourtion.com/static-code-analysis-ios-using-oclint.html 最近需要 ...
- Lint——Android SDK提供的静态代码扫描工具
Lint和FindBugs一样,都是静态代码扫描工具,区别在于它是Android SDK提供的,会检查Android项目源文件的正确性.安全性.性能.可用性等潜在的bug并优化改进. 下图简单地描述了 ...
- Objective C静态代码扫描和代码质量管理 OClint + SonarQube
OClint是针对C, C++及Objective C代码的静态扫描分析工具,而SonarQube是一个开源的代码质量管理平台.本文将实现将OClint的扫描结果导入到SonarQube中,已实现对O ...
- Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序
静态代码块:用staitc声明,jvm加载类时执行,仅执行一次构造代码块:类中直接用{}定义,每一次创建对象时执行.执行顺序优先级:静态块,main(),构造块,构造方法. 构造函数 public H ...
随机推荐
- 7、linux快捷键
ctrl +a:切换到命令行开始 ctrl+e:切换到命令行结尾 ctrl+c:终止当前命令或脚本 ctrl+d:退出当前shell,相当于exit ctrl+l:清除当前屏幕的内容,相当于clear ...
- 5、修改oracle的字符集
注意:修改字符集前需要将表空间进行数据泵备份: 5.1.修改server端字符集: 1.登录到oracle实例查看字符集: [oracle@slave-node2 ~]$ echo $ORACLE_S ...
- Redis主从,集群部署及迁移
工作中有时会遇到需要把原Redis集群下线,迁移到另一个新的Redis集群的需求(如机房迁移,Redis上云等原因).此时原Redis中的数据需要如何操作才可顺利迁移到一个新的Redis集群呢? 本节 ...
- 【网络编程】HTTP简介&URL
目录 前言 1. http 简介 1.1 概念 1.2 原理 1.3 特点 2. URL 简介 2.1 概念 2.2 URL 通用格式 2.3 网页地址 实例说明 3. HTTP 消息结构 3.1 客 ...
- Mweb发布blog到各博客平台
Mweb发布blog到各博客平台 主流博客平台 博客平台 博客园 CSDN 51CTO 博客类型 MetaWeblog API MetaWeblog API MetaWeblog API 博客网址 h ...
- 1.3.9、通过权重 Weight匹配
server: port: 8080 spring: application: name: gateway cloud: gateway: routes: - id: guo-system1 uri: ...
- Adaptive AUTOSAR 学习笔记 2 - 官方文档下载及阅读建议
目前互联网上没有太多的 Adaptive AUTOSAR 的学习资料,官方文档是一个很不错的途径.看过官方文档才发现,目前很多关于 Adaptive AUTOSAR 的文章都是官方文档的简化翻译,不如 ...
- ESP32-websocket笔记
基于ESP-IDF4.1 #include <stdio.h> #include "esp_wifi.h" #include "esp_system.h&qu ...
- python 10篇 操作mysql
一.操作数据库 使用pip install pymysql,安装pymysql模块,使用此模块连接MySQL数据库并操作数据库. import pymysql host = 'ip地址' # 链接的主 ...
- java+selenium UI自动化001
selenium是一个用于Web应用程序测试的工具,可以用来模拟用户在浏览器上的操作. 支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Googl ...