一、静态代码分析

        静态代码分析是一种通过检查代码而不是执行程序来发现源代码中错误的手段。通常可以帮助我们发现常见的编码错误,例如:

  • 语法错误

  • 违反制定的标准编码

  • 未定义的变量

  • 安全性问题

静态代码分析可以通过评估编写的代码来提高代码质量;可以稳定的运行且可以轻松自动化;增加了在源代码中发现漏洞的可能性,从而提高应用安全;由于是针对源码扫描可以在离线的开发环境中完成。但是静态代码分析并不能完全保证编写的代码没有Bug,它也有一些缺点,例如:

  • 误报问题,发现了一个不是错误的错误。

  • 静态分析的规则需要特定维护,并非总是适用。

  • 系统和第三方库可能无法分析。

二、为何需对Lua代码进行静态分析 

Lua脚本语言在性能方面非常出色、语法简单且容易上手。目前有相当多的游戏服务器和客户端程序都是使用它来开发功能业务。Lua属于解释性语言,编写的逻辑代码只有在程序运行的过程才会发现逻辑错误,而一些较隐藏的分支可能要经过很长时间的运行才能触发错误。未发现的错误如果在正式环境中触发将会产生不可预估的损失。

如何发现更多的错误,除了通过更加详细的测试外,还可以利用工具来弥补,下面列举了一些平时常见的错误问题,如果使用静态扫描分析工具是很容易发现的。

1. 变量的作用域问题[1],定义的变量在超出了作用域外使用。

1 function demo(param)
2 if param then
3 local var = param.smobj:get_var()
4 -- do_something()
5 end
6 -- 声明的`var`变量在超出作用域后访问
7 local new_var = var + 3
8 end

2. 变量的作用域问题[2],超出作用域变量作为条件判断

 1 function demo(param)
2 if param then
3 local var = param.smobj:get_var()
4 -- do_something()
5 end
6 if var then
7 -- 永远无法执行到,但不会报错
8 local new_var = var + 10
9 -- do_something()
10 end
11 end

3. 参数未定义,经常出现在代码复制-粘贴的时候,未修改完全

 1 function Player:set_world_pos(x, y)
2 do_something(x,y)
3 if condition_false then
4 log("set_world_pos x:%s, y:%s", x, y)
5 end
6 end
7 function Player:set_pos(cx, cy)
8 do_something(cx, cy)
9 if condition_false then
10 -- 这里是从上面拷贝,但是传参没有修改
11 -- 代码不会报错但行为已经错了。
12 log("set_pos x:%s , y:%s", x, y)
13 end
14 end

4. 变量拼写错误,很常见但不易察觉。

1 -- 由于拼写错误,这个只有在重载文件或者热更文件出现
2 -- 出现就会导致数据丢失,所谓一个粗心导致的大错
3 g_player_mng = g_plater_mng or {}
4 -- do_something

5. 判空逻辑问题[1],先使用变量,后进行空值判断

1 function demo()
2 local var = self:get_value()
3 local count = #var
4 -- 先拿变量进行了操作,然后才判断空值情况
5 if var then
6 self:do_something()
7 end
8 end 

6. 判空逻辑问题[2],判空的覆盖不全,后面继续使用了空值变量。

 1 function demo()
2 local var = self:get_value()
3 if var then
4 count = #var
5 end
6 local r, b = self:get_data()
7 if b then
8 -- 虽然前面对var判空了
9 -- 但是没有进行处理,这里就继续使用了。
10 table.insert(var, r)
11 end
12 end

7. 类成员方法声明写错,“.”“:” 经常写错。

1 -- 写类的成员方法的时候漏写了self 或者 :写成了.
2 function Player.set_hp(var)
3 if self.mHp > var then
4 self.mHp = var
5 end
6 end 

8. 方法调用时,“.”“:” 写错。

1 function Player:demo2(param)
2 -- 少传了参数self
3 self.demo()
4 -- 多传入了参数self.dos
5 self.dos:demoe(self.dos)
6 end

上面这些错误来自平时项目中血与泪的教训,如果能够通过静态代码扫描工具提前发现这些错误,那对提高代码的质量是非常有帮助和有价值的事情。目前市面上可以使用腾讯的TscanCode来对代码扫描,支持的语言也挺多的。

我也尝试花几篇文章来介绍一下如何编写一个简单的Lua代码扫描工具,主要介绍大体编写代码的逻辑流程。

   文章来自我的公众号,大家如果有兴趣可以关注,具体扫描关注下图。

【Lua篇】静态代码扫描分析(一)初步介绍的更多相关文章

  1. 【Lua篇】静态代码扫描分析(四)规则检查

    一.前言 通过前面三篇文章已经初步实现了将Lua源代码文件读取解析成语法树,现在就可以通过得到的语法树进行指定规则的代码扫描检查.下图简单列举了一下单个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. linux 查看目录大小

    查看当前目录下各个目录大小容量 du -sh * du -sh /app/* du -h --max-depth=1 .

  2. layui table 使用table放输入框时控制每列的宽度

    <table class="layui-table" lay-filter="demo"> <colgroup> <%--设置每列 ...

  3. layui table 表格上添加日期控件

    方法一: var tableInit = table.render({ elem: '#tbtxrz' , method: 'post' , data: jsonData , height: &quo ...

  4. hdu 1116 敌兵布阵 线段树 区间求和 单点更新

    线段树的基本知识可以先google一下,不是很难理解 线段树功能:update:单点增减 query:区间求和 #include <bits/stdc++.h> #define lson ...

  5. UVA 10887 set或hash

    题意: 给出n个A串和m个B串,将这A串与B串连接(B接在A后面)可以生成n*m个AB串,求不同的AB串的数量 分析: set直接水过 #include <bits/stdc++.h> u ...

  6. Redis 底层数据结构之跳跃表

    文章参考 <Redis 设计与实现>黄建宏 Redis(2) 跳跃表 跳跃表 跳跃表 skiplist 是一种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节 ...

  7. JavaWeb入门知识梳理

    万维网 Web App(Web应用程序)是一种可以通过万维网访问的应用程序,用户只需要连接互联网和计算机安装浏览器,即可通过URI在线使用某个Web App,而不需要再安装客户端到计算机上.Web A ...

  8. 适合企业的CRM系统选型法则?

    在市场竞争激烈的今天,企业需要找到一款好用的企业CRM系统来帮助维护客户关系,同时也能够帮助企业进行销售管理.营销管理,CRM可以说是当代企业管理的最强工具之一.那么适合企业的CRM客户管理系统要如何 ...

  9. Linux | Linux常用指令学习笔记

    @ 目录 前言 1. Linux目录结构: 2. 运行级别: init.systemctl 3. vim相关快捷键: 4. 开关机相关命令: shutdowm.halt.reboot.sync.log ...

  10. Java:Java单例中的懒汉和饿汉模式

    1.懒汉模式 懒汉模式:在类加载的时候不被初始化,懒汉式是延时加载,他是在需要的时候才创建对象. public class JdbcUtil { //定义私有的引用 private static Jd ...