summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Stocker <chregu@php.net>2004-07-12 13:04:01 +0000
committerChristian Stocker <chregu@php.net>2004-07-12 13:04:01 +0000
commit14a61929b97f1c533a6a956be556b2c90409d95e (patch)
tree1a3c2a4de3c2841decffa41a0c97993823a46ee1
parent08486a0ea3e613d06ca305781ac7050fd0f791d7 (diff)
downloadphp-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.c52
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();