diff options
author | Christian Stocker <chregu@php.net> | 2004-07-12 13:04:01 +0000 |
---|---|---|
committer | Christian Stocker <chregu@php.net> | 2004-07-12 13:04:01 +0000 |
commit | 14a61929b97f1c533a6a956be556b2c90409d95e (patch) | |
tree | 1a3c2a4de3c2841decffa41a0c97993823a46ee1 | |
parent | 08486a0ea3e613d06ca305781ac7050fd0f791d7 (diff) | |
download | php-git-14a61929b97f1c533a6a956be556b2c90409d95e.tar.gz |
implement the clone code for the XSLTProcessor object and fix #29108
"xslt segfaults when ze1_compatibility_mode is on" (By Rob Richards)
-rw-r--r-- | ext/xsl/php_xsl.c | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c index 7d51e0ec14..44908be596 100644 --- a/ext/xsl/php_xsl.c +++ b/ext/xsl/php_xsl.c @@ -70,10 +70,57 @@ ZEND_GET_MODULE(xsl) /* {{{ xsl_objects_clone */ void xsl_objects_clone(void *object, void **object_clone TSRMLS_DC) { - /* TODO */ + xsl_object *intern = (xsl_object *) object; + xsl_object *clone; + zval *tmp; + zend_class_entry *class_type; + + class_type = intern->std.ce; + + clone = emalloc(sizeof(xsl_object)); + clone->std.ce = class_type; + clone->std.in_get = 0; + clone->std.in_set = 0; + clone->ptr = NULL; + clone->prop_handler = NULL; + clone->parameter = NULL; + clone->hasKeys = intern->hasKeys; + clone->registerPhpFunctions = 0; + + ALLOC_HASHTABLE(clone->std.properties); + zend_hash_init(clone->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(clone->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + ALLOC_HASHTABLE(clone->parameter); + zend_hash_init(clone->parameter, 0, NULL, ZVAL_PTR_DTOR, 0); + + *object_clone = (void *) clone; } /* }}} */ +zend_object_value xsl_objects_store_clone_obj(zval *zobject TSRMLS_DC) +{ + zend_object_value retval; + void *new_object; + xsl_object *intern; + struct _store_object *obj; + zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); + + obj = &EG(objects_store).object_buckets[handle].bucket.obj; + + if (obj->clone == NULL) { + zend_error(E_CORE_ERROR, "Trying to clone uncloneable object of class %s", Z_OBJCE_P(zobject)->name); + } + + obj->clone(obj->object, &new_object TSRMLS_CC); + + retval.handle = zend_objects_store_put(new_object, obj->dtor, obj->free_storage, obj->clone TSRMLS_CC); + intern = (xsl_object *) new_object; + intern->handle = retval.handle; + retval.handlers = Z_OBJ_HT_P(zobject); + + return retval; +} + /* {{{ xsl_objects_free_storage */ void xsl_objects_free_storage(void *object TSRMLS_DC) { @@ -134,7 +181,8 @@ PHP_MINIT_FUNCTION(xsl) zend_class_entry ce; memcpy(&xsl_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - + xsl_object_handlers.clone_obj = xsl_objects_store_clone_obj; + REGISTER_XSL_CLASS(ce, "XSLTProcessor", NULL, php_xsl_xsltprocessor_class_functions, xsl_xsltprocessor_class_entry); #if HAVE_XSL_EXSLT exsltRegisterAll(); |