Throw type_error.321 for discarded values in to_bon8

write_bon8_value silently skipped discarded values, but the array/object
count marker still counted them, so [1, discarded] produced 82 91: a marker
announcing two elements followed by one. Throw type_error.321 like the other
binary writers do, at any nesting level.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-10-10 13:24:20 +02:00
1 parent 07ec1a4e31
commit fe7a90063d
5 files changed
+62 -5

No files matched your search

@@ -41,6 +41,8 @@ With (2), the bytes written before the exception remain in the output adapter.
above 9223372036854775807, which BON8 cannot represent
- Throws [type_error.316](../../home/exceptions.md#jsonexceptiontype_error316) if `j` contains a string that is not
valid UTF-8
- Throws [type_error.321](../../home/exceptions.md#jsonexceptiontype_error321) if `j` or a value nested in it is
discarded; example: `"cannot serialize discarded value to BON8"`
## Complexity
+1 -1
View File
@@ -810,7 +810,7 @@ does not list an enumerator and it is therefore converted like the first listed
A discarded value (one created by [`parse()`](../api/basic_json/parse.md) with a callback that returns `false` for the
value, or by default-constructing a [`basic_json`](../api/basic_json/index.md) with
[`value_t::discarded`](../api/basic_json/value_t.md)) was passed to a binary serialization function, either directly or
nested in an array or object. There is no way to represent a discarded value in CBOR, MessagePack, UBJSON, BJData, or BSON.
nested in an array or object. There is no way to represent a discarded value in CBOR, MessagePack, UBJSON, BJData, BSON, or BON8.
!!! failure "Example message"
@@ -809,6 +809,8 @@ class binary_writer
/*!
@param[in] j JSON value to serialize
@throw type_error.321 if @a j or a value nested in it is discarded
*/
void write_bon8(const BasicJsonType& j)
{
@@ -2570,6 +2572,8 @@ class binary_writer
@param[in] j JSON value to serialize
@param[in,out] string_open whether the output ends with a non-empty
string that has not been terminated with 0xFF
@throw type_error.321 if @a j or a value nested in it is discarded
*/
void write_bon8_value(const BasicJsonType& j, bool& string_open)
{
@@ -2678,7 +2682,7 @@ class binary_writer
case value_t::discarded:
default:
break;
throw_on_discarded(j, "BON8");
}
}
+5 -1
View File
@@ -22426,6 +22426,8 @@ class binary_writer
/*!
@param[in] j JSON value to serialize
@throw type_error.321 if @a j or a value nested in it is discarded
*/
void write_bon8(const BasicJsonType& j)
{
@@ -24187,6 +24189,8 @@ class binary_writer
@param[in] j JSON value to serialize
@param[in,out] string_open whether the output ends with a non-empty
string that has not been terminated with 0xFF
@throw type_error.321 if @a j or a value nested in it is discarded
*/
void write_bon8_value(const BasicJsonType& j, bool& string_open)
{
@@ -24295,7 +24299,7 @@ class binary_writer
case value_t::discarded:
default:
break;
throw_on_discarded(j, "BON8");
}
}
+49 -2
View File
@@ -82,9 +82,56 @@ TEST_CASE("BON8")
{
SECTION("discarded")
{
// discarded values are not serialized
// a discarded value cannot be serialized to BON8
const json j = json::value_t::discarded;
CHECK(json::to_bon8(j).empty());
CHECK_THROWS_WITH_AS(json::to_bon8(j), "[json.exception.type_error.321] cannot serialize discarded value to BON8", json::type_error&);
}
SECTION("discarded values nested in a container")
{
const json discarded = json::value_t::discarded;
SECTION("in a small array")
{
const json j = {1, discarded};
#if JSON_DIAGNOSTICS
CHECK_THROWS_WITH_AS(json::to_bon8(j), "[json.exception.type_error.321] (/1) cannot serialize discarded value to BON8", json::type_error&);
#else
CHECK_THROWS_WITH_AS(json::to_bon8(j), "[json.exception.type_error.321] cannot serialize discarded value to BON8", json::type_error&);
#endif
}
SECTION("as a small object value")
{
json j;
j["a"] = discarded;
#if JSON_DIAGNOSTICS
CHECK_THROWS_WITH_AS(json::to_bon8(j), "[json.exception.type_error.321] (/a) cannot serialize discarded value to BON8", json::type_error&);
#else
CHECK_THROWS_WITH_AS(json::to_bon8(j), "[json.exception.type_error.321] cannot serialize discarded value to BON8", json::type_error&);
#endif
}
SECTION("in a large array")
{
const json j = {1, 2, 3, 4, 5, discarded};
#if JSON_DIAGNOSTICS
CHECK_THROWS_WITH_AS(json::to_bon8(j), "[json.exception.type_error.321] (/5) cannot serialize discarded value to BON8", json::type_error&);
#else
CHECK_THROWS_WITH_AS(json::to_bon8(j), "[json.exception.type_error.321] cannot serialize discarded value to BON8", json::type_error&);
#endif
}
SECTION("as a large object value")
{
json j = {{"a", 1}, {"b", 2}, {"c", 3}, {"d", 4}, {"e", 5}};
j["f"] = discarded;
#if JSON_DIAGNOSTICS
CHECK_THROWS_WITH_AS(json::to_bon8(j), "[json.exception.type_error.321] (/f) cannot serialize discarded value to BON8", json::type_error&);
#else
CHECK_THROWS_WITH_AS(json::to_bon8(j), "[json.exception.type_error.321] cannot serialize discarded value to BON8", json::type_error&);
#endif
}
}
SECTION("null")