#5529·json

from_cbor()/from_msgpack() 在解码时不验证文本字符串中的 UTF-8(只有 dump() 会验证)

作者: nlohmann创建于 2026年9月15日更新于 2026年9月17日
标签kind: bugstate: please discusssolution: proposed fixaspect: binary formats

说明

取自 cbor ()'(并通过同一代码路径取自 msgpack ()' ) 解码 CBOR/MessagePack 文本字符串,方法是将其生字节复制成字符串-t'而不验证其是否为良好的UTF-8. RFC 8949§3.1要求CBOR主要类型3 (文本字符串) 包含"UTF- 8 字符串",并拒绝不规范的UTF-8 行为—— 但是这个库推迟检查为dump ()',因此从 cbor ()'本身既不扔也不返回无效的UTF-8 有效载荷的废弃值。 无效的字节仅作为后期错误表面,如果和当产生的值被序列化回JSON文本时.

  • 复制

翻译: #包括"nlohmann/json.hpp" .

包括 " 电流 "

使用json = nlohmann:::json; 2.

英寸主( ) { // CBOR: 0x62 = 文本字符串,长度 2;有效载荷 0xC0 0xAE 无效 UTF-8 std:: vector生={0x62,0xc0,0xae};

自动获取 = json: from cbor(raw, / *strict */ true,/ *allow unitions */false) ; std:: cout QQ"被丢弃:"得到.is 被丢弃()QQ"\n"; // 假 std::: cout QQ"类型:"得到.type name () QQ"\n"; // 字符串

得到.dump (); // 扔出 json. 例外. type error.316 : /"指数0:0xC0时无效的UTF-8字节" {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?


因此,`从 cbor()'报告成功(一个正常的、非被丢弃的`字符串'值)输入CBOR spec需要拒绝;这个错误只有在以后才会出现,并且只有在呼叫者恰好将 ' dump()'(或另一个UTF-8敏感操作)调用到所产生的值时才会出现。

追踪到[`binary reader:::get string ()'](https://GitHub.com/nlohmann/json/blob/3bfe2b6da7393af5cf68c44f58a1058e60499e2/包括/nlohmann/detail/input/binary reader.hpp#L3300-L3305),直接转发到`get bytes ()'——一个没有UTF-8检查的生字节副本. 与文本/JSON lixer(在扫描(`scan string ()' in lexer.hpp')时确实验证UTF-8)和`dump ()'本身验证(`type error.316')相矛盾。

为什么这看起来值得一看

- [`docs/features/binary formats/bson.md'](https://json.nlohmann.me/features/binary formats/bson/#deserialization)明确记录了类似的BSON宽大处理,它自己的"Lenient BSON输入处理"警告和一个逃生舱("在将其分别传递到‘从 bson()'之前分别验证"). 在[CBOR docs](https://json.nlohmann.me/features/binary formats/cbor/)或[出自 cbor`API docs](https://json.nlohmann.me/api/basic json/出自-cbor/)上,我找不到相应的CBOR/MessagePack说明,因此,目前我找不到这种具体的推迟验证行为。
- 意思是`来自-cbor (.,/*allow Excusions-=*/假)'—— 专为避免例外和获得`被丢弃的'寄出错误输入的信号而使用的模式—— 实际无法捕捉到这一类不正确的输入;如果呼叫者不同时在那里验证UTF-8,则该例外日后仍可能从不相关的呼叫(`dump()')中浮出.

建议的固定/替代办法

(a) 验证 UTF-8 in
. . . . . . .