Description
Three reader behaviours deviate from bsonspec.org and are not documented on the BSON feature page. Leniency is a defensible choice here, but it should be an explicit one — the docs currently imply spec conformance.
1. Array element keys are not validated. parse_bson_element_list(is_array=true) (include/nlohmann/detail/input/binary_reader.hpp:392) reads each key and discards it. The spec requires array keys to be the decimal strings "0", "1", … in order.
2. Boolean accepts any non-zero byte. case 0x08 (binary_reader.hpp:343) does sax->boolean(get() != 0). The spec permits only \x00 and \x01.
3. Binary subtype 0x02 is passed through raw. Subtype 0x02 ("Binary (old)") carries its own inner int32 length prefix per spec; the reader returns those four bytes as part of the payload.
Reproduction steps / Minimal code example
#include <nlohmann/json.hpp>
#include <iostream>
using json = nlohmann::json;
int main()
{
// 1. array with keys "x" and "9" instead of "0" and "1"
std::cout << json::from_bson(std::vector<std::uint8_t>{
0x1a, 0x00, 0x00, 0x00,
0x04, 'a', 0x00,
0x12, 0x00, 0x00, 0x00,
0x10, 'x', 0x00, 0x01, 0x00, 0x00, 0x00,
0x10, '9', 0x00, 0x02, 0x00, 0x00, 0x00,
0x00,
0x00
}).dump() << '\n';
// 2. boolean encoded as 0x02
std::cout << json::from_bson(std::vector<std::uint8_t>{
0x0a, 0x00, 0x00, 0x00,
0x08, 'a', 0x00, 0x02,
0x00
}).dump() << '\n';
// 3. binary subtype 0x02 with inner length prefix
std::cout << json::from_bson(std::vector<std::uint8_t>{
0x15, 0x00, 0x00, 0x00,
0x05, 'a', 0x00,
0x08, 0x00, 0x00, 0x00,
0x02,
0x04, 0x00, 0x00, 0x00,
0x01, 0x02, 0x03, 0x04,
0x00
}).dump() << '\n';
}
Expected vs. actual results
Actual:
{"a":[1,2]}
{"a":true}
{"a":{"bytes":[4,0,0,0,1,2,3,4],"subtype":2}}
Expected: either a parse_error for (1) and (2) and the inner prefix stripped for (3), or — if the lenient behaviour is intentional — an explicit statement of it on the BSON feature page so users relying on from_bson() for validation are not misled.
Compiler and operating system
g++ 13.3.0 (Ubuntu 24.04), -std=c++11 -O2, Linux x86-64
Library version
develop @ 06ac77f
Description
Three reader behaviours deviate from bsonspec.org and are not documented on the BSON feature page. Leniency is a defensible choice here, but it should be an explicit one — the docs currently imply spec conformance.
1. Array element keys are not validated.
parse_bson_element_list(is_array=true)(include/nlohmann/detail/input/binary_reader.hpp:392) reads each key and discards it. The spec requires array keys to be the decimal strings"0","1", … in order.2. Boolean accepts any non-zero byte.
case 0x08(binary_reader.hpp:343) doessax->boolean(get() != 0). The spec permits only\x00and\x01.3. Binary subtype
0x02is passed through raw. Subtype0x02("Binary (old)") carries its own innerint32length prefix per spec; the reader returns those four bytes as part of the payload.Reproduction steps / Minimal code example
Expected vs. actual results
Actual:
{"a":[1,2]} {"a":true} {"a":{"bytes":[4,0,0,0,1,2,3,4],"subtype":2}}Expected: either a
parse_errorfor (1) and (2) and the inner prefix stripped for (3), or — if the lenient behaviour is intentional — an explicit statement of it on the BSON feature page so users relying onfrom_bson()for validation are not misled.Compiler and operating system
g++ 13.3.0 (Ubuntu 24.04),
-std=c++11 -O2, Linux x86-64Library version
develop@ 06ac77f