From fec9e8a4f2df708dc98e17e69f98823797f91f33 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Fri, 17 Jul 2015 08:24:43 +0200 Subject: [PATCH] prohibit C++11 move from Document to Value As reported in #387, silently moving a `GenericDocument` to a `GenericValue` can lead to object slicing and premature deletion of the owning allocator of the (surviving) `GenericValue`. To reduce this risk, prohibit move construction of a `GenericValue` from a `GenericDocument`. --- include/rapidjson/document.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index d0f1c8fa3..f5c1be9d3 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -69,6 +69,9 @@ RAPIDJSON_NAMESPACE_BEGIN template class GenericValue; +template +class GenericDocument; + //! Name-value pair in a JSON object value. /*! This class was internal to GenericValue. It used to be a inner struct. @@ -446,6 +449,16 @@ class GenericValue { //! Copy constructor is not permitted. GenericValue(const GenericValue& rhs); +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Moving from a GenericDocument is not permitted. + template + GenericValue(GenericDocument&& rhs); + + //! Move assignment from a GenericDocument is not permitted. + template + GenericValue& operator=(GenericDocument&& rhs); +#endif + public: //! Constructor with JSON value type. @@ -1792,7 +1805,7 @@ class GenericDocument : public GenericValue { #if RAPIDJSON_HAS_CXX11_RVALUE_REFS //! Move constructor in C++11 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT - : ValueType(std::move(rhs)), + : ValueType(std::forward(rhs)), // explicit cast to avoid prohibited move from Document allocator_(rhs.allocator_), ownAllocator_(rhs.ownAllocator_), stack_(std::move(rhs.stack_)),