You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Read reads up to len(p) bytes into p. It returns the number of bytes
// read (0 <= n <= len(p)) and any error encountered. Even if Read
// returns n < len(p), it may use all of p as scratch space during the call.
在 Go 的 encoding/json 标准库的 decoder 中先会用长度为 512 的 []byte 来调用 io.Reader.Read() (ext 的实现) ,当第 512 字节是转义符号的时候处理是没有追加到返回中,而是跳过了。这时候 io.Reader.Reader() 返回的 n 是 511。然后如果剩下的内容还很长,第二次继续读取的时候会以 1025 长度的输入来调用函数,然而 ext 中的实现,因为上一次是标记了转义(这里导致少返回一个字节),这次会多插入一个字节(这里导致多插入一个字节,并且由于 p := b[:0] 这里会导致 p 提前后移,后面的内容就都重复了)。
简单尝试了一下在 Reader 结构中加一个 buffer []byte 来存多余的部分,但由于现在的实现 p 有的时候会一次追加 2 个字节导致循环过程修改了本身内容,不太好做,可以讨论一下有什么好的办法。
问题
在特定的 JSON 文本环境,Ext 中
encoding/json
部分对转义字符处理实现有问题,会导致 go 的标准库encoding/json
直接崩溃。特定环境是,当 JSON 文本的第 512 个字节刚好是\
的时候,会造成崩溃。因为我刚好遇到了 JSON 文本刚好第 512 个字节开始是 path 部分,如:\/v2ray.com
表现
环境
分析
崩溃的原因是 io.Reader.Read() 返回的结果长度大于传入 []byte 的长度。
io.Reader.Read() 的注释里有如下描述:
在 Go 的
encoding/json
标准库的 decoder 中先会用长度为 512 的 []byte 来调用 io.Reader.Read() (ext 的实现) ,当第 512 字节是转义符号的时候处理是没有追加到返回中,而是跳过了。这时候 io.Reader.Reader() 返回的 n 是 511。然后如果剩下的内容还很长,第二次继续读取的时候会以 1025 长度的输入来调用函数,然而 ext 中的实现,因为上一次是标记了转义(这里导致少返回一个字节),这次会多插入一个字节(这里导致多插入一个字节,并且由于p := b[:0]
这里会导致p
提前后移,后面的内容就都重复了)。简单尝试了一下在 Reader 结构中加一个
buffer []byte
来存多余的部分,但由于现在的实现p
有的时候会一次追加 2 个字节导致循环过程修改了本身内容,不太好做,可以讨论一下有什么好的办法。上面我应该描述清楚了,简单写了个测试用例可以来测试: dawndiy@da0a47f#diff-7d2da6197eab2fafc43d39c5180a853c
The text was updated successfully, but these errors were encountered: