一、前言

通过前面三篇文章已经初步实现了将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_bvar_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篇】静态代码扫描分析(四)规则检查的更多相关文章

  1. 【Lua篇】静态代码扫描分析(一)初步介绍

    一.静态代码分析         静态代码分析是一种通过检查代码而不是执行程序来发现源代码中错误的手段.通常可以帮助我们发现常见的编码错误,例如: 语法错误 违反制定的标准编码 未定义的变量 安全性问 ...

  2. 【Lua篇】静态代码扫描分析(三)语法分析

    一.语法分析 通过将词法分析获取的Token流按照目标语言的语法进行解析的过程,例如解析函数声明.函数调用.变量声明.各种语句等. 二.Lua语法分析 在写语法分析程序前,先需要了解Lua的语句和语法 ...

  3. 【Lua篇】静态代码扫描分析(二)词法分析

    一.词法分析 词法分析(英语:lexical analysis)是计算机科学中将字符序列转换为单词(Token)序列的过程.进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer, ...

  4. 静态代码扫描工具PMD定制xml的规则(一)操作篇

    0.前言 PMD作为开源的静态代码扫描工具有很强的扩展能力,可使用java或xpath定制rule.第一篇从操作上讲解如何定制一个用于扫描xml是否规范的规则.首先我们知道xml格式的文件在java工 ...

  5. DEVOPS技术实践_05:sonar静态代码扫描

    一.SonarQube静态代码扫描平台 1.1 安装 https://www.sonarqube.org/官网 1.2 下载软件包 https://www.sonarqube.org/download ...

  6. 使用OClint进行iOS项目的静态代码扫描

    使用OClint进行iOS项目的静态代码扫描 原文链接:http://blog.yourtion.com/static-code-analysis-ios-using-oclint.html 最近需要 ...

  7. Lint——Android SDK提供的静态代码扫描工具

    Lint和FindBugs一样,都是静态代码扫描工具,区别在于它是Android SDK提供的,会检查Android项目源文件的正确性.安全性.性能.可用性等潜在的bug并优化改进. 下图简单地描述了 ...

  8. Objective C静态代码扫描和代码质量管理 OClint + SonarQube

    OClint是针对C, C++及Objective C代码的静态扫描分析工具,而SonarQube是一个开源的代码质量管理平台.本文将实现将OClint的扫描结果导入到SonarQube中,已实现对O ...

  9. Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序

    静态代码块:用staitc声明,jvm加载类时执行,仅执行一次构造代码块:类中直接用{}定义,每一次创建对象时执行.执行顺序优先级:静态块,main(),构造块,构造方法. 构造函数 public H ...

随机推荐

  1. AcWing 241. 楼兰图腾

    #include<bits/stdc++.h> using namespace std; const int N=2e5+5; typedef long long ll; ll ans,l ...

  2. yum安装GitLab-v11.11.8(git私服)

    GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务.(跟github.gitee类似) 1. 安装依赖软件 $ yum -y install ...

  3. mybatis 配置的log4j文件无效,不能正常显示日志信息

    正在学习mybatis,配置好后log4j.properties文件后,日志信息不能正常显示,没有效果. 查看了一下mybatis的相关文档,在日志一栏找到问题愿意 原因是我们的mybatis选了其他 ...

  4. chrome 屏蔽广告的利器

    Adblock Plus https://chrome.google.com/webstore/detail/adblock-plus/cfhdojbkjhnklbpkdaibdccddilifddb ...

  5. Java学习笔记之—Java基础

    将学习到的JAVA基础用xmind记录了下来,需要原件的可以私信

  6. VisibleDeprecationWarning , Creating an ndarray from ragged nested sequences... 警告怎么办

    我不是完美主义,但是至少,我在做实验的时候不能容忍有 warning 的出现. 今天使用 tensorflow.keras.datasets中的 imdb 数据集,使用 imdb.load_data( ...

  7. NPOI库读写Excel文件

    //首先Nuget安装NPOI库using System; using System.Data; using System.IO; using NPOI.HSSF.UserModel; using N ...

  8. Charles使用笔记001

    一.抓电脑的请求 Proxy-->勾选Windows Proxy 二.Charles 拦截原理 三.Charles 拦截修改数据 选择一个链接-->右键-->勾选Breakpoint ...

  9. [刘阳Java]_SpringMVC与Struts2的对比_第12讲

    今日来具体给讲讲SpringMVC与Struts2的对比,这样方便朋友们在工作中或者是面试学习中对这两者的区别有个更好的了解 把这张图放在这里,我是想说SpringMVC和Struts2真的是不一样的 ...

  10. js树形数据结构的扁平化

    前面我们封装了一维数组(具备树形结构相关属性)处理成树形结构的方法:https://www.cnblogs.com/coder--wang/p/15013664.html 接下来我们来一波反向操作,封 ...