JSON Specification and usage of BOM/charset-encoding
我一直在阅读RFC-4627规范,并开始解释:
当以
这些扣款是正确的吗?在实现遵循这种解释的Web服务或Web客户机时,我会遇到问题吗?我是否应该针对违反上述两个属性的Web浏览器提交Bug?
你是对的
RFC 7159,第8.1节:好的。
Implementations MUST NOT add a byte order mark to the beginning of a JSON text.
Ok.
这是尽可能清楚的。这是整个RFC中唯一的"不得"。好的。
RFC 7159,第11节:好的。
The MIME media type for JSON text is application/json.
Type name: application
Subtype name: json
Required parameters: n/a
Optional parameters: n/a
[...]
Note: No"charset" parameter is defined for this registration.Ok.
JSON编码
json的唯一有效编码是utf-8、utf-16或utf-32,并且由于第一个字符(如果有多个字符,则前两个字符)的unicode值始终小于128(没有可以包含前两个字符的更高值的有效json文本),因此始终可以知道哪一个有效编码和哪一个有效编码是仅通过查看字节流使用了ndianness。好的。RFC建议
JSONRFC说前两个字符总是低于128,您应该检查前4个字节。好的。
我换一种说法:因为字符串"1"也是有效的JSON,所以不能保证您有两个字符——更不用说4个字节了。好的。我的建议
我对确定JSON编码的建议略有不同:好的。
快速方法:好的。
(实际上,这里唯一有效的字符是一个ASCII数字)
(这些必须是没有前导"0"、
(它必须是一个ASCII数字,编码为UTF-16,big endian)
(它必须是一个ASCII数字,编码为UTF-16,小尾数)
(同样,没有前导"0"的ASCII数字、
00 00 00 xx —是UTF-32BE00 xx 00 xx —是UTF-16BExx 00 00 00 —是utf-32lexx 00 xx 00 —是UTF-16LExx xx xx xx —是UTF-8
但只有当它确实是这些编码中的一个有效字符串时,它才能工作,而这可能不是。此外,即使在5个有效编码中有一个有效字符串,它可能仍然不是有效的JSON。好的。
我的建议是进行比RFC中包含的更严格的验证,以验证您是否:好的。
仅查找nul字节是不够的。好的。
尽管如此,在任何时候都不需要任何bom字符来确定编码,也不需要mime字符集——这两个字符在JSON中都是不需要和无效的。好的。
在使用utf-16和utf-32时,您只需要使用二进制内容传输编码,因为它们可能包含nul字节。UTF-8没有这个问题,8bit内容传输编码也很好,因为它在字符串中不包含nul(尽管它仍然包含大于等于128的字节,所以7位传输将不起作用-有utf-7可以用于这种传输,但它不会是有效的json,因为它不是唯一有效的json编码之一)。好的。
有关更多详细信息,请参阅此答案。好的。回答你的后续问题
Are these correct deductions?
Ok.
对。好的。
Will I run into problem when implementing web-services or web-clients which adhere to this interpretations?
Ok.
可能,如果您与不正确的实现进行交互。为了与不正确的实现进行互操作,您的实现可能会忽略BOM-请参见RFC 7159,第1.8节:好的。
In the interests of interoperability, implementations
that parse JSON texts MAY ignore the presence of a byte order mark
rather than treating it as an error.Ok.
此外,忽略mime字符集是兼容JSON实现的预期行为-请参阅RFC 7159,第11节:好的。
Note: No"charset" parameter is defined for this registration.
Adding one really has no effect on compliant recipients.Ok.
安全注意事项
我个人并不认为总是需要默默地接受不正确的JSON流。如果您决定接受带有bom和/或mime字符集的输入,那么您必须回答这些问题:好的。
- 如果mime字符集和实际编码不匹配,该怎么办?
- 如果bom和mime字符集不匹配,该怎么办?
- 如果BOM和实际编码不匹配,该怎么办?
- 当它们都不同时该怎么办?
- 除了UTF-8/16/32之外的编码怎么办?
- 您确定所有的安全检查都会按预期工作吗?
将编码定义在三个独立的地方——JSON字符串本身、BOM和mime字符集中——这使得问题不可避免:如果它们不一致,该怎么做。除非你拒绝这样的输入,否则没有一个明显的答案。好的。
例如,如果您有一个代码验证JSON字符串,以查看是否可以安全地用JavaScript对其进行评估-它可能会被mime字符集或bom误导,并将其视为与实际不同的编码,而不检测它是否使用正确编码时将检测到的字符串。(HTML的类似问题在过去导致了XSS攻击。)好的。
每当您决定接受带有多个可能相互冲突的编码指标的不正确的JSON字符串时,您必须为所有这些可能性做好准备。并不是说永远不应该这样做,因为您可能需要使用由不正确的实现生成的输入。我只是想说,你需要彻底考虑其中的含义。好的。不合格实施
Should I file bugs against web browsers which violate the the two properties above?
Ok.
当然-如果他们称之为JSON,并且实现不符合JSONRFC,那么这是一个bug,应该这样报告。好的。
您是否发现了任何不符合JSON规范的特定实现,但它们都会宣传这样做?好的。好啊。
关于问题1,我认为您是正确的,因为第3节关于前两个字符是ASCII和关于BOM的Unicode FAQ,请参阅"Q:我应该如何处理BOM?",回答第3部分。你对"必须"的强调可能有点强烈:常见问题似乎意味着应该。
不知道问题2的答案。