Several functions set the type of a value before creating the string,
array, object, or binary value it stands for. When that creation threw -
std::bad_alloc from the allocator, say - the value was left behind with
the new type but nothing behind it:
- json::binary() returned no value, but its destructor asserted that a
binary value has a binary array, aborting debug builds.
- operator[], push_back, emplace_back, emplace, and update turned a null
value into an array or object that did not exist; any later access
dereferenced a null pointer.
- The to_json conversions destroyed the old value first. A failed
creation of the new one left a pointer to the destroyed old value,
which was then used and freed again (heap-use-after-free).
The value is now created first and the type set after it, and to_json
destroys the old value only once the new one exists, so a failed
allocation leaves the value unchanged.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>