Lua - 空值判断的几种情况
【摘要】 在安全领域,lua编程语言因为其小巧在众多工具上都作为插件开发语言,常见的有openresty,nmap等。因此笔者将会开辟一个Lua相关的系列文章,主要记录工作过程中一些领悟或者是一些踩过的坑,希望能够借此平台帮助到读者们。
0x00 背景
最近在写一段nginx+redis的代码,主要基于openresty,其中使用到了lua-resty-redis库。我平时写代码都比较小心,针对外部输入的值一般都会进行异常判断,大概的代码如下:
local redis = require "redis"
local cjson = require "cjson"
--[[省略部分代码]]
local ok, err = redis:get("key")
if not ok thenngx.log(ngx.ERR, '[ERROR]:', err)return
end
local data = cjson.decode(ok)
在decode这里出现了错误提示,但是ok并没有为空或者nil,不然代码是走不到这里来。
发现问题后,我们就在前面打印一下ok数据的类型吧,大概的代码如下:
ngx.log(ngx.ERR, 'ok type: ', type(ok))
if not ok then-- TODO
end
这个时候我们得到的结果是userdata,这个东西算是一种复杂结构体,一般都是跨语言产生的,比如ffi.C这些。当时我的思路大概也是这样,肯定redis存放的数据是二进制的,但是呀,存放什么数据都是我自己控制的,不可能有什么畸形数据,因此这一点也排除了。最后在自己查看中发现,其实就是这个key不存在。
0x01 分析
既然原因找到了,我们就去看看为什么会这样,主要通过阅读lua-resty-redis的源码:
local function _read_reply(self, sock)local line, err = sock:receive()if not line thenif err == "timeout" and not rawget(self, "_subscribed") thensock:close()endreturn nil, errendlocal prefix = byte(line)if prefix == 36 then -- char '$'-- print("bulk reply")local size = tonumber(sub(line, 2))if size < 0 thenreturn nullendlocal data, err = sock:receive(size)if not data thenif err == "timeout" thensock:close()endreturn nil, errendlocal dummy, err = sock:receive(2) -- ignore CRLFif not dummy thenreturn nil, errendreturn dataelseif prefix == 43 then -- char '+'-- print("status reply")return sub(line, 2)elseif prefix == 42 then -- char '*'local n = tonumber(sub(line, 2))-- print("multi-bulk reply: ", n)if n < 0 thenreturn nullendlocal vals = new_tab(n, 0)local nvals = 0for i = 1, n dolocal res, err = _read_reply(self, sock)if res thennvals = nvals + 1vals[nvals] = reselseif res == nil thenreturn nil, errelse-- be a valid redis error valuenvals = nvals + 1vals[nvals] = {false, err}endendreturn valselseif prefix == 58 then -- char ':'-- print("integer reply")return tonumber(sub(line, 2))elseif prefix == 45 then -- char '-'-- print("error reply: ", n)return false, sub(line, 2)else-- when `line` is an empty string, `prefix` will be equal to nil.return nil, "unknown prefix: \"" .. tostring(prefix) .. "\""end
end
从上面的源码可以看到,在读取redis服务器返回数据的时候,如果某些格式不正确,比如数据长度的字节小于0这样的异常情况,函数就会返回null,注意是null不是nil。
这个null的定义来自ngx.null,这个东西可以追溯到其官方文档lua-nginx-module.
The ngx.null constant is a NULL light userdata usually used to represent nil values in Lua tables etc and is similar to the lua-cjson library’s cjson.null constant.
从上面描述看,ngx.null就是一个代表null的userdata结构,类似一个自定义的类,但是没有什么具体含义,同时文档里面也提到了类似的值还有cjson.null,以后小心被坑。
0x02 扩展
同时文档中还提到了,使用ngx.log对几个空值进行字符串打印的时候
nil会显示成“nil”,
逻辑值会显示成“true”或者“false”,
ngx.null会被显示成“null”。
来源:华为云社区 作者:HuangJacky
Lua - 空值判断的几种情况相关推荐
- 怎么判断油烟净化器需要清洗?出现这三种情况,需要及时清洗!
众所周知,由于工作环境复杂,油烟净化器在日常使用过程中需要经常清洁和维护.但是至于何时需要清洁油烟净化器,餐饮公司的许多朋友可能不知道.那么如何确定油烟净化器是否需要清洗呢?今天,天珑小编介绍三种情况 ...
- C++编程练习 计算一元二次方程组解判断是否测试过三种情况
原题来自菜鸟教程 C++ 实例 - 求一元二次方程的根 实现方法相当简单 就是最基础的C语言程序 以下是菜鸟教程给的答案-- #include <iostream> #include &l ...
- python空值赋0_Python中的空值判断
本文中所有代码均运行在Python 2.7上 在实际的工作当中,我们难免要与空值打交道,相信不少初学者都会写出下面的代码: if a is None: do something. else: do t ...
- optional空值判断_Java 8 Optional不仅用于替换空值
optional空值判断 总览 在Java 8中,您可以返回Optional而不是返回null. 就像您在Java 7中所做的那样.这可能会有所不同,这取决于您是否倾向于忘记检查null还是使用静态代 ...
- if语句判断真假的几种情况
在写二叉树的最后判断二叉树是否为空的时候遇到if语句的判断竟然跟想得不一样!于是深入地了解了下if语句的判断真假的几种情况,发现还真有点东西-(自己果然是菜鸡hhhhhhhh) 这个是书本上的 i = ...
- 进一步封装axios并调用其读取数据(吐槽~在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据)
注意!!!(修改于2020年7月18日) 在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据 报错截图如下 报错内容: {&quo ...
- 2021-10-11 ! AVL树 及其平衡调整 四种情况 恋上数据结构笔记 (考过)
b站有个up讲的很详细 https://www.bilibili.com/video/BV1xE411h7dd?from=search&seid=11383601726930144190&am ...
- sql中索引不会被用到的几种情况
转载自 sql中索引不会被用到的几种情况 1.查询谓词没有使用索引的主要边界,换句话说就是select *,可能会导致不走索引. 比如,你查询的是SELECT * FROM T WHERE Y=XX ...
- Linux系统编程16:进程控制之进程终止以及终止进程的三种情况
文章目录 (1)进程终止时的三种情况 (2)退出进程的方法 A:正常退出-exit和return的区别 B:异常退出 C:_exit()函数 (3)实践 (1)进程终止时的三种情况 一个进程结束了,无 ...
最新文章
- 安卓高手之路之java层Binder
- 【原创】基于ARM的流水灯仿真示例
- 用户控件如何控制ASPX页面的控件
- 任务调度之Quartz1
- 娄底二中高考2021成绩查询,2021年娄底高考状元名单公布,娄底高考状元学校资料及最高分...
- web---SSL/TSL
- T-SQL查询字符串的字节数和字符个数
- 精选JAVA毕业设计83套——源码+论文完整资源
- php安装libpng,安装php:configure: error: libpng.(a|so) not found解决办法
- Zedgraph 总结
- java 文档查看技巧
- 常用的统计抽样分布和正态总体的抽样分布
- 怎么把柱形图和折线图放在一起_Excel图表制作:柱形图和折线图的组合图案例...
- 小米公司开源 MIUI 6 第三方适配工具 『Patchrom』
- 知乎-知乎网站-复制文字-破解知乎复制
- SAP全球副总裁、中国区总经理李强,离职去向大家就不要猜了
- NAMD跑分子动力学模拟出现的一些问题(更新中)
- 分布式锁-Redis解决方案和Redisson解决方案
- srtm数据格式.hgt读取
- Java实现单点登录(SSO)方式
热门文章
- java最大最小距离算法缺点_java算法(蓝桥杯)- 算法提高 题目1 最大最小值
- java写的教育管理的项目_干货分享|推荐12款适合做Java后台管理系统的项目
- python语音播放文本_python将文本转化成语音并播放
- 鸿蒙系统 闹钟,华为鸿蒙2.0操作系统正式版
- python 折线图 尾部_Matplotlib 折线图plot()所有用法详解
- Nginx http 视频点播服务器搭建操作指南
- 贡献分选择结果——Teamwork
- Python 第一章 基础知识
- USACO / Factorials (简单模拟)
- textread读取记事本文件