一、前言

通过前面三篇文章已经初步实现了将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. 第9章:Ingress

    9.1 Ingress为弥补NodePort不足而生 1 单独用service暴露服务的方式,在实际生产环境中不太合适 ClusterIP 只能在集群内部访问. NodePort 方式的话,测试环境使 ...

  2. gRPC(3):拦截器

    在 gRPC 调用过程中,我们可以拦截 RPC 的执行,在 RPC 服务执行前或执行后运行一些自定义逻辑,这在某些场景下很有用,例如身份验证.日志等,我们可以在 RPC 服务执行前检查调用方的身份信息 ...

  3. php 经典的算法题-偷苹果

    有5个人偷了一堆苹果,准备在第二天分赃.晚上,有一人遛出来,把所有菜果分成5份,但是多了一个,顺手把这个扔给树上的猴了,自己先拿1/5藏了.没想到其他四人也都是这么想的,都如第一个人一样分成5份把多的 ...

  4. Linux文件目录结构详解 (转)

      整理自<鸟哥的私房菜> 对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能, ...

  5. Windows 上连接蓝牙耳机

    "开始"菜单 –> 输入蓝牙 点击蓝牙设备,选择连接设备即可.

  6. 一款不错的 Go Server/API boilerplate,使用 K8S+DDD+CQRS+ES+gRPC 最佳实践构建

    Golang API Starter Kit 该项目的主要目的是使用最佳实践.DDD.CQRS.ES.gRPC 提供样板项目设置. 为开发和生产环境提供 kubernetes 配置.允许与反映生产的 ...

  7. DIY一个智能开关kwswitch

    源码地址:https://gitee.com/kerwincui/kwswitch 平台简介 该智能开关平台包括服务端.硬件端.PC端和安卓端.硬件使用ESP8266模块,成本相对较低,可以发挥想象力 ...

  8. 我的第一个MVC程序(SpringMVC的环境搭建与实例运用)

    做一个完整点的mvc框架的搭建流程吧 Spring包含jar包下载 SpingMVC是基于Spring的一种关于web的解决方案,所以,使用springMVC,首先要准备有关Spring的一些jar包 ...

  9. java测试银行系统源代码

    1 package Kaoshi; 2 3 /*信1705-3 20173442 田昕可*/ 4 import java.util.*; 5 import java.io.*; 6 7 class A ...

  10. Day12 抽象类、接口、内部类-面向对象编程(3)

    抽象类 abstract修饰符可以用来修饰方法也可以用来修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类: 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类. ...