mirror of
https://github.com/nlohmann/json.git
synced 2026-11-04 11:49:22 +00:00
- unit-custom-object-key-type: drop the redundant member initializer and return a braced init list (clang-tidy); direct-initialize the converted value, as copy-initialization makes GCC 4.8 instantiate the copy constructor, which needs a range constructor strict_object lacks - unit-stream-bulk-scan: pick the claimed get area size by tag dispatch instead of a constant condition (MSVC C4127) - unit-allocator: skip the parser callback and sax_parse sweeps with Clang 3.4 and 3.5, which leak memory when an element constructor throws inside a libstdc++ std::map copy or std::vector reallocation Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
3 files changed
+25
-4
No files matched your search
@@ -1167,6 +1167,10 @@ TEST_CASE("parse() survives a failing allocation at every point (#5985)")
|
|||||||
// terminates the program instead of throwing std::bad_alloc. Nothing to
|
// terminates the program instead of throwing std::bad_alloc. Nothing to
|
||||||
// check there.
|
// check there.
|
||||||
#if !(defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL > 0)
|
#if !(defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL > 0)
|
||||||
|
// Clang 3.4 and 3.5 leak memory when an element constructor throws
|
||||||
|
// inside libstdc++'s containers (a std::map copy, a std::vector
|
||||||
|
// reallocation), without any json value involved.
|
||||||
|
#if !(defined(__clang__) && !defined(__apple_build_version__) && __clang_major__ == 3 && __clang_minor__ < 6)
|
||||||
SECTION("parser callback")
|
SECTION("parser callback")
|
||||||
{
|
{
|
||||||
const auto keep_all = [](int /*depth*/, sweep_json::parse_event_t /*event*/, sweep_json& /*parsed*/) noexcept
|
const auto keep_all = [](int /*depth*/, sweep_json::parse_event_t /*event*/, sweep_json& /*parsed*/) noexcept
|
||||||
@@ -1201,5 +1205,6 @@ TEST_CASE("parse() survives a failing allocation at every point (#5985)")
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -160,12 +160,12 @@ class strict_key
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_value{};
|
std::string m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
strict_key make_strict_key(const std::string& key)
|
strict_key make_strict_key(const std::string& key)
|
||||||
{
|
{
|
||||||
return strict_key(key.c_str());
|
return {key.c_str()};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Key, class Value, class Compare, class Allocator>
|
template<class Key, class Value, class Compare, class Allocator>
|
||||||
@@ -224,7 +224,9 @@ TEST_CASE("converting a value with keys that cannot be made from a std::string n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const strict_json converted = value;
|
// direct-initialization: a copy-initialization makes GCC 4.8 instantiate the
|
||||||
|
// copy constructor, which needs a range constructor strict_object lacks
|
||||||
|
const strict_json converted(value);
|
||||||
|
|
||||||
// at() needs to make a std::string of a key for its error message
|
// at() needs to make a std::string of a key for its error message
|
||||||
const auto member = [](const strict_json & object, const char* name) -> const strict_json &
|
const auto member = [](const strict_json & object, const char* name) -> const strict_json &
|
||||||
|
|||||||
@@ -120,6 +120,20 @@ class oversized_get_area_streambuf : public std::streambuf
|
|||||||
private:
|
private:
|
||||||
std::array<char, 8> m_data{{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}};
|
std::array<char, 8> m_data{{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// the size the oversized_get_area_streambuf claims: 3 GiB with a 64-bit
|
||||||
|
// std::size_t, else 0 to skip the test (tag dispatch, as a constant condition
|
||||||
|
// triggers MSVC's C4127)
|
||||||
|
template<std::size_t SizeOfSizeT>
|
||||||
|
std::size_t oversized_get_area_size(std::integral_constant<std::size_t, SizeOfSizeT> /*unused*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t oversized_get_area_size(std::integral_constant<std::size_t, 8> /*unused*/)
|
||||||
|
{
|
||||||
|
return std::size_t{3} << 30u;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// how a test reads from the stream
|
// how a test reads from the stream
|
||||||
@@ -466,7 +480,7 @@ TEST_CASE("parsing from a std::istream scans the get area in bulk")
|
|||||||
SECTION("skipping more characters than gbump() takes at once")
|
SECTION("skipping more characters than gbump() takes at once")
|
||||||
{
|
{
|
||||||
// gbump() takes an int, but a get area can be larger
|
// gbump() takes an int, but a get area can be larger
|
||||||
const std::size_t claimed = sizeof(std::size_t) < 8 ? 0 : std::size_t{3} << 30u;
|
const std::size_t claimed = oversized_get_area_size(std::integral_constant<std::size_t, sizeof(std::size_t)>());
|
||||||
oversized_get_area_streambuf buf(claimed);
|
oversized_get_area_streambuf buf(claimed);
|
||||||
if (claimed == 0 || static_cast<std::size_t>(buf.in_avail()) != claimed)
|
if (claimed == 0 || static_cast<std::size_t>(buf.in_avail()) != claimed)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user