From c033292aeaf014accfb5b4054d8fdac36358266c Mon Sep 17 00:00:00 2001 From: ylavic Date: Sat, 27 Apr 2019 03:41:19 +0200 Subject: [PATCH] Safer GenericValue& operator=(GenericValue& rhs). When rhs is a sub-Value of *this, destroying *this also destroys/frees rhs, thus the following RawAssign(rhs) crashes. Address this by saving/moving rhs to a temporary first, which clears rhs and avoids its destruction with *this. The crash can be reproduced in test Value.MergeDuplicateKey by using the CrtAllocator instead of the default Document's MemoryPoolAllocator. --- include/rapidjson/document.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 0910122..61d031b 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -916,8 +916,13 @@ public: */ GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { if (RAPIDJSON_LIKELY(this != &rhs)) { + // Can't destroy "this" before assigning "rhs", otherwise "rhs" + // could be used after free if it's an sub-Value of "this", + // hence the temporary danse. + GenericValue temp; + temp.RawAssign(rhs); this->~GenericValue(); - RawAssign(rhs); + RawAssign(temp); } return *this; }