Diagnose two silently violated template parameter requirements
Both were on the list of requirements that are not caught at compile time and corrupt values rather than failing, and both are a plain size comparison: - A BinaryType whose value_type is wider than one byte, which the readers and writers reinterpret as raw bytes anyway. - A NumberUnsignedType too narrow to hold the absolute value of every NumberIntegerType value, which makes basic_json(INT64_MIN).dump() yield -0 for std::int64_t with std::uint32_t. Neither static_assert rejects a configuration that worked before: both only fire where the result was already wrong. Also add the two comments the review asked for, in write_bson_string() and calc_bson_array_size(), matching the ones their counterparts already carry. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
3 files changed
+34
No files matched your search
@@ -1060,6 +1060,8 @@ class binary_writer
|
|||||||
oa->write_characters(
|
oa->write_characters(
|
||||||
reinterpret_cast<const CharType*>(value.data()),
|
reinterpret_cast<const CharType*>(value.data()),
|
||||||
value.size());
|
value.size());
|
||||||
|
// the terminating null byte is written explicitly rather than taken
|
||||||
|
// from the buffer, so that string_t::data() need not be null-terminated
|
||||||
oa->write_character(to_char_type(0x00));
|
oa->write_character(to_char_type(0x00));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1151,6 +1153,9 @@ class binary_writer
|
|||||||
|
|
||||||
const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
|
const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
|
||||||
{
|
{
|
||||||
|
// the index is built as a std::string, while calc_bson_element_size
|
||||||
|
// takes a string_t; convert explicitly, as the two are only
|
||||||
|
// implicitly convertible for some string types
|
||||||
const auto key = std::to_string(array_index++);
|
const auto key = std::to_string(array_index++);
|
||||||
return result + calc_bson_element_size(string_t(key.data(), key.size()), el);
|
return result + calc_bson_element_size(string_t(key.data(), key.size()), el);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -403,6 +403,18 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
// Two template parameter requirements that would otherwise be silently
|
||||||
|
// violated: neither produces a diagnostic of its own, and both corrupt
|
||||||
|
// values rather than failing.
|
||||||
|
|
||||||
|
static_assert(sizeof(typename BinaryType::value_type) == 1,
|
||||||
|
"BinaryType::value_type must be exactly one byte wide, "
|
||||||
|
"because the binary readers and writers reinterpret the container's storage as raw bytes");
|
||||||
|
|
||||||
|
static_assert(sizeof(NumberUnsignedType) >= sizeof(NumberIntegerType),
|
||||||
|
"NumberUnsignedType must be at least as wide as NumberIntegerType, "
|
||||||
|
"because it has to hold the absolute value of every NumberIntegerType value");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// helper for exception-safe object creation
|
/// helper for exception-safe object creation
|
||||||
|
|||||||
@@ -18109,6 +18109,8 @@ class binary_writer
|
|||||||
oa->write_characters(
|
oa->write_characters(
|
||||||
reinterpret_cast<const CharType*>(value.data()),
|
reinterpret_cast<const CharType*>(value.data()),
|
||||||
value.size());
|
value.size());
|
||||||
|
// the terminating null byte is written explicitly rather than taken
|
||||||
|
// from the buffer, so that string_t::data() need not be null-terminated
|
||||||
oa->write_character(to_char_type(0x00));
|
oa->write_character(to_char_type(0x00));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18200,6 +18202,9 @@ class binary_writer
|
|||||||
|
|
||||||
const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
|
const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
|
||||||
{
|
{
|
||||||
|
// the index is built as a std::string, while calc_bson_element_size
|
||||||
|
// takes a string_t; convert explicitly, as the two are only
|
||||||
|
// implicitly convertible for some string types
|
||||||
const auto key = std::to_string(array_index++);
|
const auto key = std::to_string(array_index++);
|
||||||
return result + calc_bson_element_size(string_t(key.data(), key.size()), el);
|
return result + calc_bson_element_size(string_t(key.data(), key.size()), el);
|
||||||
});
|
});
|
||||||
@@ -21886,6 +21891,18 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
// Two template parameter requirements that would otherwise be silently
|
||||||
|
// violated: neither produces a diagnostic of its own, and both corrupt
|
||||||
|
// values rather than failing.
|
||||||
|
|
||||||
|
static_assert(sizeof(typename BinaryType::value_type) == 1,
|
||||||
|
"BinaryType::value_type must be exactly one byte wide, "
|
||||||
|
"because the binary readers and writers reinterpret the container's storage as raw bytes");
|
||||||
|
|
||||||
|
static_assert(sizeof(NumberUnsignedType) >= sizeof(NumberIntegerType),
|
||||||
|
"NumberUnsignedType must be at least as wide as NumberIntegerType, "
|
||||||
|
"because it has to hold the absolute value of every NumberIntegerType value");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// helper for exception-safe object creation
|
/// helper for exception-safe object creation
|
||||||
|
|||||||
Reference in new issue
Block a user