mirror of
https://github.com/nlohmann/json.git
synced 2026-10-05 14:10:31 +00:00
Fix allocation failure during JSON destruction
Signed-off-by: Michael Sam <michaelsam94@users.noreply.github.com> Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
committed by
Niels Lohmann
parent
5185181552
commit
ae43e8ded4
@@ -40,7 +40,9 @@ using ordered_json = nlohmann::ordered_json;
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
#include <new>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@@ -107,6 +109,49 @@ DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
|
||||
|
||||
using float_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, float>;
|
||||
|
||||
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
||||
namespace
|
||||
{
|
||||
bool fail_next_global_allocation = false;
|
||||
|
||||
void* checked_malloc(std::size_t size)
|
||||
{
|
||||
if (fail_next_global_allocation)
|
||||
{
|
||||
fail_next_global_allocation = false;
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
if (void* const result = std::malloc(size))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void* operator new (std::size_t size)
|
||||
{
|
||||
return checked_malloc(size);
|
||||
}
|
||||
|
||||
void* operator new[](std::size_t size)
|
||||
{
|
||||
return checked_malloc(size);
|
||||
}
|
||||
|
||||
void operator delete (void* ptr) noexcept
|
||||
{
|
||||
std::free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr) noexcept
|
||||
{
|
||||
std::free(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// for #1647
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
@@ -940,4 +985,19 @@ TEST_CASE("regression test - excessive binary container size honors allow_except
|
||||
CHECK(json::from_cbor(std::vector<std::uint8_t> {0x9b, 0, 0, 0, 0, 0, 0, 0, 0x02}, true, false).is_discarded());
|
||||
}
|
||||
|
||||
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
|
||||
TEST_CASE("regression test #5135 - destructor tolerates stack allocation failure")
|
||||
{
|
||||
{
|
||||
json j = json::array({json::array({1, 2}), json::object({{"key", json::array({3})}})});
|
||||
fail_next_global_allocation = true;
|
||||
}
|
||||
|
||||
const bool allocation_failure_was_injected = !fail_next_global_allocation;
|
||||
fail_next_global_allocation = false;
|
||||
|
||||
CHECK(allocation_failure_was_injected);
|
||||
}
|
||||
#endif
|
||||
|
||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||
|
||||
Reference in New Issue
Block a user