nlohmann / json

JSON for Modern C++
https://json.nlohmann.me
MIT License
41.3k stars 6.58k forks source link

CBOR data cannot be decoded #4301

Closed GitHobi closed 4 months ago

GitHobi commented 4 months ago

Description

I have the following CBOR data: 0xA2, 0x01, 0x02, 0x03, 0x26 I try to decode this, using this code:

std::vector<std::uint8_t> v = {0xA2, 0x01, 0x02, 0x03, 0x26};
json j = json::from_cbor(v);
auto j_str = to_string(j);
std::cout << std::setw(2) << j << std::endl;  

The code fails with this exception:

parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x01

However in https://cbor.me/ this data decodes without issues. This form of maps is used in Fido2, so I consider it valid (check at https://www.w3.org/TR/webauthn-1/#conforming-all-classes, searching for "Example 2).

Reproduction steps

Take the above line so of code and compile it.

Expected vs. actual results

The library is not able to decode the given byte stream - I consider the data as valid CBOR, so it should be possible to decode it.

Minimal code example

No response

Error messages

No response

Compiler and operating system

PlatformIO, GCC

Library version

3.11.03

Validation

nlohmann commented 4 months ago

I am confused. Shouldn't 0xA2 start a map? Then I would indeed expect a string starting at byte 2.

GitHobi commented 4 months ago

Hi. Yes, it should start a map! But not a map with "string" to "anything", CBOR also allows a map with "int" to "anything", too.

Here is an example from the Webauthn documentation:

A5 01 02 03 26 20 01 21 58 20 65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d 22 58 20 1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c

if you push this trough "cbor.me" you get:

{1: 2, 3: -7, -1: 1, -2: h'65EDA5A12577C2BAE829437FE338701A10AAA375E1BB5B5DE108DE439C08551D', -3: h'1E52ED75701163F7F9E40DDF9F341B3DC9BA860AF7E0CA7CA7E9EECD0084D19C'}

I'm not an expert in CBOR - but it seems that a map does not need to start with a string as key. So this is seems to be valid "CBOR".

nlohmann commented 4 months ago

This is not supported, since JSON does not support non-string object keys. See documentation: https://json.nlohmann.me/features/binary_formats/cbor/#deserialization