【Lua篇】静态代码扫描分析(一)

简介: 静态代码分析是一种通过检查代码而不是执行程序来发现源代码中错误的手段。通常可以帮助我们发现常见的编码错误,例如:语法错误 违反制定的标准编码 未定义的变量安全性问题 静态代码分析可以通过评估编写的代码来提高代码质量;可以稳定的运行且可以轻松自动化;增加了在源代码中发现漏洞的可能性,从而提高应用安全;由于是针对源码扫描可以在离线的开发环境中完成。但是静态代码分析并不能完全保证编写的代码没有Bug,它也有一些缺点,

【Lua篇】静态代码扫描分析(一)


一、静态代码分析


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


  • 语法错误


  • 违反制定的标准编码


  • 未定义的变量


  • 安全性问题


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


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


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

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

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


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


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


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


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


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


function demo(param)
    if param then
        local var = param.smobj:get_var()
        -- do_something()
    end
    if var then
        -- 永远无法执行到,但不会报错
        local new_var = var + 10    
        -- do_something()
    end
end


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


function Player:set_world_pos(x, y) 
    do_something(x,y)
    if condition_false then
        log("set_world_pos x:%s, y:%s", x, y)
    end
end
function Player:set_pos(cx, cy) 
    do_something(cx, cy)
    if condition_false then
        -- 这里是从上面拷贝,但是传参没有修改
        -- 代码不会报错但行为已经错了。
        log("set_pos  x:%s , y:%s", x, y)   
    end
end


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


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


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


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


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


function demo() 
    local var = self:get_value()
    if var then
        count = #var
    end
    local r, b = self:get_data()
    if b then
        -- 虽然前面对var判空了
        -- 但是没有进行处理,这里就继续使用了。
        table.insert(var, r)   
    end
end


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


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


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


function Player:demo2(param)
    -- 少传了参数self
    self.demo()  
    -- 多传入了参数self.dos
    self.dos:demoe(self.dos)  
end


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


       我也尝试花几篇文章来介绍一下如何编写一个简单的Lua代码扫描工具,主要介绍大体的逻辑流程。欢迎微信搜索"游戏测试开发"关注一起沟通交流。

相关文章
|
6月前
|
C++ 索引 Python
Lua中self 、自索引及其面向对象应用代码示例
Lua中self 、自索引及其面向对象应用代码示例
|
5月前
|
监控 数据处理 开发者
利用Lua代码简化局域网管理软件开发
使用Lua脚本语言可以提升局域网管理软件的开发效率和代码可维护性。示例包括:使用LuaSocket扫描局域网设备;通过动态加载和应用配置文件展示配置管理;利用实时监控功能,当网络流量超过阈值时触发警报;以及通过HTTP POST自动提交监控数据到服务器。Lua的简洁语法和强大功能简化了网络管理和自动化任务。
111 3
|
5月前
|
数据挖掘 Linux 数据处理
探索Linux下的Lua命令:轻量级脚本语言在数据处理和分析中的应用
**探索Linux上的Lua:轻量级脚本语言用于数据处理。Lua通过命令行解释器执行,适用于游戏开发、数据分析及自动化。特点包括小巧、高效、可扩展和动态类型。使用`lua`或`luajit`,配合-e、-l、-i参数执行脚本或互动模式。示例:执行`hello.lua`脚本打印"Hello, Lua!"。最佳实践涉及版本兼容、性能优化、使用C API、测试和文档编写。**
|
5月前
|
JSON 监控 数据格式
使用Lua代码扩展上网行为管理软件的脚本功能
本文介绍了如何使用Lua脚本增强上网行为管理,包括过滤URL、记录用户访问日志、控制带宽和自动提交监控数据到网站。Lua是一种轻量级语言,适合编写扩展脚本。文中提供多个示例代码,如URL过滤器、用户活动日志记录器和带宽控制器,帮助用户根据需求定制网络管理功能。通过这些示例,用户可以快速掌握Lua在上网行为管理中的应用。
171 4
|
6月前
|
存储 监控 数据管理
Lua代码解析:实现上网行为监管软件的自定义规则引擎
在当今数字化时代,网络安全和数据隐私保护备受关注。为了确保网络安全和合规性,许多组织和机构需要监管和管理其员工或用户的上网行为。为了实现这一目标,开发一款高效的上网行为监管软件至关重要。本文将介绍如何使用Lua语言开发一种自定义规则引擎,以实现上网行为监管软件的自定义规则引擎。
226 0
|
JavaScript 前端开发 C++
[√]lua binding模版文件分析
[√]lua binding模版文件分析
79 0
|
C++
[✔️]unreal插件lua-profiler:分析lua性能
[✔️]unreal插件lua-profiler:分析lua性能
363 0
|
消息中间件 数据采集 Java
Lua集成kafka第三方插件代码介绍|学习笔记
快速学习Lua集成kafka第三方插件代码介绍
Lua集成kafka第三方插件代码介绍|学习笔记
|
1月前
|
缓存 分布式计算 NoSQL
大数据-43 Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
大数据-43 Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
27 2