From 85507088051bdfabf8bc71346290949b78c3c914 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Tue, 10 Sep 2013 05:21:18 -0700 Subject: Fixed various crashes because hidden pointers were not persistently stored Copying the result value of a function has been fixed New C++ nullptr type is supported for Php::Value --- src/value.cpp | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) (limited to 'src/value.cpp') diff --git a/src/value.cpp b/src/value.cpp index f386822..7f43724 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -41,6 +41,16 @@ Value::Value() ZVAL_NULL(_val); } +/** + * Constructor for null ptr + */ +Value::Value(std::nullptr_t value) +{ + // create a null zval + MAKE_STD_ZVAL(_val); + ZVAL_NULL(_val); +} + /** * Constructor based on integer value * @param value @@ -197,15 +207,37 @@ Value &Value::operator=(const Value &value) // skip self assignment if (this == &value) return *this; - // destruct the zval (this function will decrement the reference counter, - // and only destruct if there are no other references left) - zval_ptr_dtor(&_val); - - // just copy the zval, and the refcounter - _val = value._val; - - // and we have one more reference - Z_ADDREF_P(_val); + // is the object a reference? + if (Z_ISREF_P(_val)) + { + // the current object is a reference, this means that we should + // keep the zval object, and copy the other value into it, get + // the current refcount + int refcount = Z_REFCOUNT_P(_val); + + // clean up the current zval (but keep the zval structure) + zval_dtor(_val); + + // make the copy + *_val = *value._val; + zval_copy_ctor(_val); + + // restore refcount and reference setting + Z_SET_ISREF_TO_P(_val, true); + Z_SET_REFCOUNT_P(_val, refcount); + } + else + { + // destruct the zval (this function will decrement the reference counter, + // and only destruct if there are no other references left) + zval_ptr_dtor(&_val); + + // just copy the zval, and the refcounter + _val = value._val; + + // and we have one more reference + Z_ADDREF_P(_val); + } // done return *this; -- cgit v1.2.3