From 069beaa49325728e0eff0ba13fa480604ce43a84 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Thu, 20 Nov 2014 17:12:54 +0100 Subject: Fixed issue #137: Php::Object("MyClass") crashed when no __construct() function was defined in it --- include/object.h | 23 +++-------------------- zend/object.cpp | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/include/object.h b/include/object.h index 6350259..124c0b3 100644 --- a/include/object.h +++ b/include/object.h @@ -39,24 +39,7 @@ public: * or when it is a string holding a classname * @param that An other object */ - Object(const Value &value) : Value() - { - // when a string is passed in, we are going to make a new instance of the - // passed in string - if (value.isString()) - { - // instantiate the object - instantiate(value); - - // and call the __construct method - call("__construct"); - } - else - { - // this simply copies the other object - operator=(value); - } - } + Object(const Value &value); /** * Constructor to create a new instance of a builtin class @@ -183,9 +166,9 @@ private: /** * Helper method to instantiate an object * @param name Class name + * @return zend_class_entry */ - void instantiate(const char *name); - + struct _zend_class_entry *instantiate(const char *name); }; /** diff --git a/zend/object.cpp b/zend/object.cpp index dc548cc..30fdcdb 100644 --- a/zend/object.cpp +++ b/zend/object.cpp @@ -51,11 +51,39 @@ Object::Object(const char *name, Base *base) } } +/** + * Copy constructor is valid if the passed in object is also an object, + * or when it is a string holding a classname + * @param that An other object + */ +Object::Object(const Value &value) : Value() +{ + // when a string is passed in, we are going to make a new instance of the + // passed in string + if (value.isString()) + { + // instantiate the object + auto *entry = instantiate(value); + + // leap out if there is no __construct function + if (!zend_hash_exists(&entry->function_table, "__construct", 12)) return; + + // call the construct function + call("__construct"); + } + else + { + // this simply copies the other object + operator=(value); + } +} + /** * Internal method to instantiate an object - * @param name + * @param name Name of the class to instantiate + * @return zend_class_entry */ -void Object::instantiate(const char *name) +zend_class_entry *Object::instantiate(const char *name) { // we need the tsrm_ls variable TSRMLS_FETCH(); @@ -79,6 +107,8 @@ void Object::instantiate(const char *name) // @todo is this a memory leak? the base class first initializes a stdClass, // and then we overwrite it with a specific class + // return the class entry + return entry; } /** -- cgit v1.2.3