Clojure でデコードする必要がある PHP によってシリアル化された値があります。このライブラリを使用して逆シリアル化しています。EBNF/ABNF 表記法を使用して文法を定義するInstaparseを使用します。参考までに、完全な定義は次のとおりです。
<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 の専門家ではないので、ここでの選択肢を理解しようとしています。
つかむ正しい文字数としてサイズを使用することは可能ですか? それが不可能な場合、文法定義を微調整して正しい解析を有効にする方法を誰かが見ていますか?