Trying to use nlohmann/json to parse some CBOR payload:
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
uint8_t data[] = {0xa2, 0x43, 0x72, 0x65, 0x74, 0x81, 0x0d, 0x47,
0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0xf5};
json jresp = json::from_cbor(data, data + (sizeof data / sizeof data[0]));
return 0;
}
Fails with this error:
libc++abi.dylib: terminating with uncaught exception of type nlohmann::detail::parse_error: [json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x43
I tried other decoders, and those are able to decode that payload.
Python's cbor package is able to decode it:
import cbor
print(cbor.loads(b"\xa2\x43\x72\x65\x74\x81\x0d\x47\x73\x75\x63\x63\x65\x73\x73\xf5"))
{b'ret': [13], b'success': True}
CBOR playground at cbor.me is able to decode it:
16 bytes:
A2 # map(2)
43 # bytes(3)
726574 # "ret"
81 # array(1)
0D # unsigned(13)
47 # bytes(7)
73756363657373 # "success"
F5 # primitive(21)
Diagnostic:
{'ret': [13], 'success': true}
Is there some flag to pass to nlohmann/json to make it decode it?
Tried to pass strict=false
in json::from_cbor()
to no avail.
I don't have experience with CBOR but it doesn't seem to prevent you from using binary strings, integers, etc. as JSON keys.
In your case the input data uses
0x43
to define a 3-byte binary key, instead of the expected0x63
for a 3-byte string. Something similar forsuccess
.Using
{0xa2, 0x63, 0x72, 0x65, 0x74, 0x81, 0x0d, 0x67, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0xf5};
works fine with nlohmann/json.cbor.me differentiate between binary strings (single quotes) and text strings (double quotes). JSON expects/requires double quotes for strings and JSON keys are defined as strings: https://www.json.org/json-en.html
See also: https://stackoverflow.com/a/4162651/4181011
Edit:
What you have:
{'ret': [13], 'success': true}
A2 # map(2)
43 # bytes(3)
726574 # "ret"
81 # array(1)
0D # unsigned(13)
47 # bytes(7)
73756363657373 # "success"
F5 # primitive(21)
What you want/need:
{"ret": [13], "success": true}
A2 # map(2)
63 # text(3)
726574 # "ret"
81 # array(1)
0D # unsigned(13)
67 # text(7)
73756363657373 # "success"
F5 # primitive(21)
Edit 2:
You JSON is not valid. The error message says so. At byte 2 the parser expects a string which in CBOR is introduced by the string length
(0x60-0x7B) or indefinite string type (0x7F)
.Your CBOR payload does not introduce a string but bytes. That's why it is rejected by the parser.
0x43
is not a valid type/length identifier for strings and JSON requires a string at this point.