我有一个由 PHP 序列化的值,需要在 Clojure 中解码。我正在使用这个库来反序列化它;它使用Instaparse,它利用 EBNF/ABNF 符号来定义语法。作为参考,这是完整的定义:
<S> = expr
<expr> = (string | integer | double | boolean | null | array)+
<digit> = #'[0-9]'
<number> = negative* (decimal-num | integer-num)
<negative> = '-'
<integer-num> = digit+
<decimal-num> = integer-num '.' integer-num
<zero-or-one> = '0'|'1'
size = digit+
key = (string | integer)
<val> = expr
array = <'a:'> <size> <':{'> (key val)+ <'}'> <';'>?
boolean = <'b:'> zero-or-one <';'>
null = <'N;'>
integer = <'i:'> number <';'>
double = <'d:'> number <';'>
string = <'s:'> <size> <':\\\"'> #'([^\"]|\\.)*' <'\\\";'>
我在这个库中发现了一个错误 - 它无法处理包含该"
字符的序列化字符串。
php > echo serialize('{"key":"value"}');
s:15:"{"key":"value"}";
使用库反序列化,当它找到第二个时它会爆炸"
:
> (deserialize-php "s:15:\"{\"key\":\"value\"}\";")
[:index 7]
问题存在于语法定义的这一行:
string = <'s:'> <size> <':\\\"'> #'([^\"]|\\.)*' <'\\\";'>
您会注意到字符串定义不包括该"
字符。但这不正确,我可以在该字符串中包含任何字符;大小是最重要的。我不是 BNF 专家,所以我想弄清楚我的选择是什么。
是否可以使用大小作为要抓取的正确字符数?如果那不可能,有人看到我可以调整语法定义以启用正确解析的方法吗?