Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c38455c7d | ||
|
|
4571446da7 |
No files matched your search
+3
-1
@@ -178,8 +178,10 @@ function(_json_test_add_test test_name file main cxx_standard)
|
|||||||
COMMAND ${memcheck_command} $<TARGET_FILE:${test_target}> ${DOCTEST_TEST_FILTER}
|
COMMAND ${memcheck_command} $<TARGET_FILE:${test_target}> ${DOCTEST_TEST_FILTER}
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
)
|
)
|
||||||
|
# under Valgrind the slowest tests take close to 25 minutes, so ctest's
|
||||||
|
# default timeout of 1500 seconds leaves no headroom
|
||||||
set_tests_properties(${test_target}_valgrind PROPERTIES
|
set_tests_properties(${test_target}_valgrind PROPERTIES
|
||||||
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA
|
LABELS "valgrind" FIXTURES_REQUIRED TEST_DATA TIMEOUT 3600
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|||||||
@@ -3123,27 +3123,6 @@ class binary_reader
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief store the count of an optimized container (or the length of a string)
|
|
||||||
|
|
||||||
A count equal to npos is rejected: npos marks a container whose count is
|
|
||||||
not known, so a count of that value would be read as "no count" (compare
|
|
||||||
get_cbor_container_size()). No container can hold that many elements.
|
|
||||||
|
|
||||||
@param[in] count the count read from the input
|
|
||||||
@param[out] result set to @a count unless it is rejected
|
|
||||||
@return whether @a count is usable
|
|
||||||
*/
|
|
||||||
bool store_ubjson_count(const std::size_t count, std::size_t& result)
|
|
||||||
{
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(count == npos))
|
|
||||||
{
|
|
||||||
return out_of_range_error(exception_id::container_too_large, "integer value overflow", "size");
|
|
||||||
}
|
|
||||||
result = count;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief read a UBJSON/BJData optimized-container count of a signed marker
|
@brief read a UBJSON/BJData optimized-container count of a signed marker
|
||||||
type ('i', 'I', 'l', 'L') and narrow it to std::size_t
|
type ('i', 'I', 'l', 'L') and narrow it to std::size_t
|
||||||
@@ -3174,7 +3153,8 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
return out_of_range_error(exception_id::container_too_large, "integer value overflow", "size");
|
return out_of_range_error(exception_id::container_too_large, "integer value overflow", "size");
|
||||||
}
|
}
|
||||||
return store_ubjson_count(static_cast<std::size_t>(number), result); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
|
result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -3251,7 +3231,8 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return store_ubjson_count(conditional_static_cast<std::size_t>(number), result);
|
result = conditional_static_cast<std::size_t>(number);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
@@ -3269,7 +3250,8 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
return out_of_range_error(exception_id::container_too_large, "integer value overflow", "size");
|
return out_of_range_error(exception_id::container_too_large, "integer value overflow", "size");
|
||||||
}
|
}
|
||||||
return store_ubjson_count(detail::conditional_static_cast<std::size_t>(number), result);
|
result = detail::conditional_static_cast<std::size_t>(number);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
|
|||||||
@@ -2422,7 +2422,6 @@ class binary_writer
|
|||||||
nothing large has been written then, and the caller writes the
|
nothing large has been written then, and the caller writes the
|
||||||
document in two passes, which reports that error
|
document in two passes, which reports that error
|
||||||
*/
|
*/
|
||||||
template<typename SinkType = OutputSinkType, typename std::enable_if<is_detected<sink_written_t, SinkType>::value, int>::type = 0>
|
|
||||||
bool write_bson_document_single_pass(const BasicJsonType& document)
|
bool write_bson_document_single_pass(const BasicJsonType& document)
|
||||||
{
|
{
|
||||||
const std::size_t start = oa.written();
|
const std::size_t start = oa.written();
|
||||||
|
|||||||
Generated
+6
-25
@@ -21130,27 +21130,6 @@ class binary_reader
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
@brief store the count of an optimized container (or the length of a string)
|
|
||||||
|
|
||||||
A count equal to npos is rejected: npos marks a container whose count is
|
|
||||||
not known, so a count of that value would be read as "no count" (compare
|
|
||||||
get_cbor_container_size()). No container can hold that many elements.
|
|
||||||
|
|
||||||
@param[in] count the count read from the input
|
|
||||||
@param[out] result set to @a count unless it is rejected
|
|
||||||
@return whether @a count is usable
|
|
||||||
*/
|
|
||||||
bool store_ubjson_count(const std::size_t count, std::size_t& result)
|
|
||||||
{
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(count == npos))
|
|
||||||
{
|
|
||||||
return out_of_range_error(exception_id::container_too_large, "integer value overflow", "size");
|
|
||||||
}
|
|
||||||
result = count;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief read a UBJSON/BJData optimized-container count of a signed marker
|
@brief read a UBJSON/BJData optimized-container count of a signed marker
|
||||||
type ('i', 'I', 'l', 'L') and narrow it to std::size_t
|
type ('i', 'I', 'l', 'L') and narrow it to std::size_t
|
||||||
@@ -21181,7 +21160,8 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
return out_of_range_error(exception_id::container_too_large, "integer value overflow", "size");
|
return out_of_range_error(exception_id::container_too_large, "integer value overflow", "size");
|
||||||
}
|
}
|
||||||
return store_ubjson_count(static_cast<std::size_t>(number), result); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
|
result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -21258,7 +21238,8 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return store_ubjson_count(conditional_static_cast<std::size_t>(number), result);
|
result = conditional_static_cast<std::size_t>(number);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
@@ -21276,7 +21257,8 @@ class binary_reader
|
|||||||
{
|
{
|
||||||
return out_of_range_error(exception_id::container_too_large, "integer value overflow", "size");
|
return out_of_range_error(exception_id::container_too_large, "integer value overflow", "size");
|
||||||
}
|
}
|
||||||
return store_ubjson_count(detail::conditional_static_cast<std::size_t>(number), result);
|
result = detail::conditional_static_cast<std::size_t>(number);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
@@ -30412,7 +30394,6 @@ class binary_writer
|
|||||||
nothing large has been written then, and the caller writes the
|
nothing large has been written then, and the caller writes the
|
||||||
document in two passes, which reports that error
|
document in two passes, which reports that error
|
||||||
*/
|
*/
|
||||||
template<typename SinkType = OutputSinkType, typename std::enable_if<is_detected<sink_written_t, SinkType>::value, int>::type = 0>
|
|
||||||
bool write_bson_document_single_pass(const BasicJsonType& document)
|
bool write_bson_document_single_pass(const BasicJsonType& document)
|
||||||
{
|
{
|
||||||
const std::size_t start = oa.written();
|
const std::size_t start = oa.written();
|
||||||
|
|||||||
@@ -3211,32 +3211,12 @@ TEST_CASE("BJData")
|
|||||||
#endif
|
#endif
|
||||||
CHECK(json::from_bjdata(vM, true, false).is_discarded());
|
CHECK(json::from_bjdata(vM, true, false).is_discarded());
|
||||||
|
|
||||||
// the first dimension is 2^64-1, which is rejected as a count (see below)
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vMX), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
|
|
||||||
CHECK(json::from_bjdata(vMX, true, false).is_discarded());
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("optimized array: count equal to SIZE_MAX")
|
|
||||||
{
|
|
||||||
// the reader marks a container without a count by SIZE_MAX, so
|
|
||||||
// a count of that value must not be read as "no count"
|
|
||||||
// (it used to parse as [1])
|
|
||||||
json _;
|
|
||||||
#if SIZE_MAX != 0xffffffff
|
#if SIZE_MAX != 0xffffffff
|
||||||
std::vector<uint8_t> const vM = {'[', '#', 'M', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 'i', 0x01, ']'};
|
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vMX), "[json.exception.out_of_range.408] syntax error while parsing BJData size: excessive ndarray size caused overflow", json::out_of_range&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
|
|
||||||
CHECK(json::from_bjdata(vM, true, false).is_discarded());
|
|
||||||
// one less is an ordinary excessive count
|
|
||||||
std::vector<uint8_t> const vM1 = {'[', '#', 'M', 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 'i', 0x01, ']'};
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM1), "[json.exception.out_of_range.408] excessive array size: 18446744073709551614", json::out_of_range&);
|
|
||||||
#else
|
#else
|
||||||
std::vector<uint8_t> const vm = {'[', '#', 'm', 0xFF, 0xFF, 0xFF, 0xFF, 'i', 0x01, ']'};
|
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vMX), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vm), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
|
|
||||||
CHECK(json::from_bjdata(vm, true, false).is_discarded());
|
|
||||||
std::vector<uint8_t> const vL = {'[', '#', 'L', 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 'i', 0x01, ']'};
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vL), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
|
|
||||||
CHECK(json::from_bjdata(vL, true, false).is_discarded());
|
|
||||||
#endif
|
#endif
|
||||||
|
CHECK(json::from_bjdata(vMX, true, false).is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("optimized array: integer value overflow")
|
SECTION("optimized array: integer value overflow")
|
||||||
|
|||||||
@@ -2360,18 +2360,6 @@ TEST_CASE("UBJSON optimized arrays of a valueless type are bounded")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("a count equal to SIZE_MAX is rejected")
|
|
||||||
{
|
|
||||||
// the reader marks a container without a count by SIZE_MAX, so a
|
|
||||||
// count of that value must not be read as "no count"; UBJSON's
|
|
||||||
// largest count type (int64) can only reach it where size_t is 32 bits
|
|
||||||
#if SIZE_MAX == 0xffffffff
|
|
||||||
const std::vector<uint8_t> input = {'[', '#', 'L', 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 'i', 0x01, ']'};
|
|
||||||
CHECK_THROWS_WITH_AS(_ = json::from_ubjson(input), "[json.exception.out_of_range.408] syntax error while parsing UBJSON size: integer value overflow", json::out_of_range&);
|
|
||||||
CHECK(json::from_ubjson(input, true, false).is_discarded());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("ordinary counts are unaffected")
|
SECTION("ordinary counts are unaffected")
|
||||||
{
|
{
|
||||||
CHECK(json::from_ubjson(std::vector<uint8_t>({'[', '$', 'Z', '#', 'i', 3})) == json({nullptr, nullptr, nullptr}));
|
CHECK(json::from_ubjson(std::vector<uint8_t>({'[', '$', 'Z', '#', 'i', 3})) == json({nullptr, nullptr, nullptr}));
|
||||||
|
|||||||
Reference in new issue
Block a user