From b620c5b3e5e99c46bb127dc35e8710e35d7bd7f9 Mon Sep 17 00:00:00 2001 From: Justin Carpentier <justin.carpentier@inria.fr> Date: Thu, 20 Feb 2020 12:01:18 +0100 Subject: [PATCH] core: fix potential bug in rvalue_from_python_data --- .../details/rvalue_from_python_data.hpp | 55 ++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/include/eigenpy/details/rvalue_from_python_data.hpp b/include/eigenpy/details/rvalue_from_python_data.hpp index 3cd94e97..254961b9 100644 --- a/include/eigenpy/details/rvalue_from_python_data.hpp +++ b/include/eigenpy/details/rvalue_from_python_data.hpp @@ -1,3 +1,7 @@ +/* + * Copyright 2018-2020, INRIA + */ + #ifndef __eigenpy_details_rvalue_from_python_data_hpp__ #define __eigenpy_details_rvalue_from_python_data_hpp__ @@ -10,14 +14,51 @@ namespace boost { namespace converter { - + /// \brief Template specialization of rvalue_from_python_data template<typename Derived> struct rvalue_from_python_data<Eigen::MatrixBase<Derived> const & > - : rvalue_from_python_storage<Eigen::MatrixBase<Derived> const & > + : rvalue_from_python_storage<Derived const & > + { + typedef Eigen::MatrixBase<Derived> const & T; + +# if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \ +&& (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \ +&& (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \ +&& !defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing this */ + // This must always be a POD struct with m_data its first member. + BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<T>,stage1) == 0); +# endif + + // The usual constructor + rvalue_from_python_data(rvalue_from_python_stage1_data const & _stage1) + { + this->stage1 = _stage1; + } + + // This constructor just sets m_convertible -- used by + // implicitly_convertible<> to perform the final step of the + // conversion, where the construct() function is already known. + rvalue_from_python_data(void* convertible) + { + this->stage1.convertible = convertible; + } + + // Destroys any object constructed in the storage. + ~rvalue_from_python_data() + { + if (this->stage1.convertible == this->storage.bytes) + static_cast<Derived *>((void *)this->storage.bytes)->~Derived(); + } + }; + + /// \brief Template specialization of rvalue_from_python_data + template<typename Derived> + struct rvalue_from_python_data<Eigen::EigenBase<Derived> const & > + : rvalue_from_python_storage<Derived const & > { typedef Eigen::MatrixBase<Derived> const & T; - + # if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \ && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \ && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \ @@ -25,13 +66,13 @@ namespace boost // This must always be a POD struct with m_data its first member. BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<T>,stage1) == 0); # endif - + // The usual constructor rvalue_from_python_data(rvalue_from_python_stage1_data const & _stage1) { this->stage1 = _stage1; } - + // This constructor just sets m_convertible -- used by // implicitly_convertible<> to perform the final step of the // conversion, where the construct() function is already known. @@ -39,7 +80,7 @@ namespace boost { this->stage1.convertible = convertible; } - + // Destroys any object constructed in the storage. ~rvalue_from_python_data() { @@ -47,7 +88,7 @@ namespace boost static_cast<Derived *>((void *)this->storage.bytes)->~Derived(); } }; - + } } } // namespace boost::python::converter -- GitLab