JSON 校验

首先,天国的 Bulletproof。

这次讲一讲 JSON 的校验(validation)。本文水分充足。


SEBAS 中负责文本解析的是 Peg.js,用起来有点像 lex+yacc,准确说是因为它们的代码嵌入:

1
2
3
4
_TimeSecondsValue
= seconds:_FloatValue "s" {
return wrapPrimitive("time", seconds.value);
}

在这一段的最后就是一个函数体,对 _TimeSecondsValue 的解析返回的值就是函数返回的值。lex 和 yacc 也有类似的功能。不过用着真的有点不太习惯,因为编译前无法检测代码块里的错误,至少没有工具自动完成这个。

假设解析完成了,最后输出的是一个对象。我希望去检测这个对象,保证里面的成员存在性符合要求,值类型合法,格式合法,范围合法(比如视频的 AV 号必须是正整数),不冲突。一个解析器是不会给你干这个活儿的,你还得自己加个符号表,然后写一堆验证逻辑,还要递归。

所以我就突然想到了,你看,我得到的结果不也是 JSON 吗?很多网络服务也是使用 JSON 作为信息传递格式,那么为了鲁棒性,肯定会有人用某些方法去验证得到的 JSON 是否合格式要求。

所以我就去找了一下 JSON 的规范(schema,我不知道专业的怎么翻译,想写成“范式”,不过那是 form,和 schema 又不一样)校验。我用过点 Swagger,知道这玩意儿形式(不只是具体写法)如何,作用为何,怎么用。

JSON 的规范是有标准的。例子勉强够用。照猫画虎写了一些。

验证工具选择还是不少的。我一开始用的是 tv4,不过发现我得用到跨文件的 $ref 元素,而 tv4 无法处理。所以后来改用了 ajv,也懒得指定版本了,直接用最新的标准,反正向后兼容的。

基于此我写了一些规格测试,来保证返回数据的格式(同时也作为返回样例)。还别说,期间几次解析器的代码修改时真的导致了测试失败,幸好有规格测试,要不在使用返回的数据的时候就头疼了。这里是具体的测试,这足以保证返回数据里该有的都有,不该有的都没有。毕竟这是一个系统外往系统内走的环节,如果有人想在这个环节攻击,系统得有基本的防御。


不知道什么时候记的:

看现在 BAS 的样子,DIYgod 又要单刷,测试区都做了。不过这个项目虽然在 BiliBili 的账户下,不过看着各种方面,其实是他的一个个人项目而已……所以 SEBAS 就挂起了。

分享到 评论