]> granicus.if.org Git - php/commitdiff
Mostly fix Dom XPath
authorNikita Popov <nikic@php.net>
Wed, 16 Apr 2014 13:52:59 +0000 (15:52 +0200)
committerNikita Popov <nikic@php.net>
Wed, 16 Apr 2014 15:14:34 +0000 (17:14 +0200)
ext/dom/dom_iterators.c
ext/dom/node.c
ext/dom/nodelist.c
ext/dom/php_dom.c
ext/dom/php_dom.h
ext/dom/xpath.c

index 250e2efab5cc91c3c49ec09f19b66a3823406032..22d0ab0ee340f0919e5b0c6c5deab56dcad42baf 100644 (file)
@@ -197,10 +197,7 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
                if (objmap->nodetype != XML_ENTITY_NODE && 
                        objmap->nodetype != XML_NOTATION_NODE) {
                        if (objmap->nodetype == DOM_NODESET) {
-                               zval obj;
-                               ZVAL_OBJ(&obj, &objmap->baseobj->std);
-                               nodeht = HASH_OF(&obj);
-
+                               nodeht = HASH_OF(&objmap->baseobj_zv);
                                zend_hash_move_forward(nodeht);
                                if ((entry = zend_hash_get_current_data(nodeht))) {
                                        ZVAL_COPY(&iterator->curobj, entry);
@@ -275,10 +272,7 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i
                if (objmap->nodetype != XML_ENTITY_NODE && 
                        objmap->nodetype != XML_NOTATION_NODE) {
                        if (objmap->nodetype == DOM_NODESET) {
-                               zval obj;
-                               ZVAL_OBJ(&obj, &objmap->baseobj->std);
-                               nodeht = HASH_OF(&obj);
-
+                               nodeht = HASH_OF(&objmap->baseobj_zv);
                                zend_hash_internal_pointer_reset(nodeht);
                                if ((entry = zend_hash_get_current_data(nodeht))) {
                                        ZVAL_COPY(&iterator->curobj, entry);
index 920581423eb2440fea4bda5e401a41ee3c8e7a75..57669b506945701e86e2e01789c33decceeb0613 100644 (file)
@@ -1729,8 +1729,8 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{
                                        zend_string *prefix;
                                        ulong idx;
 
-                                       if (zend_hash_get_current_key_ex(Z_ARRVAL_P(tmp), 
-                                               &prefix, &idx, 0, NULL) == HASH_KEY_IS_STRING) {
+                                       if (zend_hash_get_current_key(Z_ARRVAL_P(tmp), 
+                                               &prefix, &idx, 0) == HASH_KEY_IS_STRING) {
                                                xmlXPathRegisterNs(ctxp, prefix->val, Z_STRVAL_P(tmpns));
                                        }
                                }
index 323eb9925d1c4f21ee77b927ae4e4c714a41f208..3ef43f2ac7f36ef4901e38e8c84e9a5bef185d2f 100644 (file)
@@ -64,9 +64,7 @@ int dom_nodelist_length_read(dom_object *obj, zval *retval TSRMLS_DC)
                        count = xmlHashSize(objmap->ht);
                } else {
                        if (objmap->nodetype == DOM_NODESET) {
-                               zval obj;
-                               ZVAL_OBJ(&obj, &objmap->baseobj->std);
-                               nodeht = HASH_OF(&obj);
+                               nodeht = HASH_OF(&objmap->baseobj_zv);
                                count = zend_hash_num_elements(nodeht);
                        } else {
                                nodep = dom_object_get_node(objmap->baseobj);
@@ -132,9 +130,7 @@ PHP_FUNCTION(dom_nodelist_item)
                                }
                        } else {
                                if (objmap->nodetype == DOM_NODESET) {
-                                       zval obj;
-                                       ZVAL_OBJ(&obj, &objmap->baseobj->std);
-                                       HashTable *nodeht = HASH_OF(&obj);
+                                       HashTable *nodeht = HASH_OF(&objmap->baseobj_zv);
                                        zval *entry = zend_hash_index_find(nodeht, index);
                                        if (entry) {
                                                ZVAL_COPY(return_value, entry);
index 538317295d4cd91753603453564ff5e8b7242243..a15cd255b7423b7686ec08b2780a012bdd06f4bb 100644 (file)
@@ -73,6 +73,9 @@ zend_class_entry *dom_namespace_node_class_entry;
 
 zend_object_handlers dom_object_handlers;
 zend_object_handlers dom_nnodemap_object_handlers;
+#if defined(LIBXML_XPATH_ENABLED)
+zend_object_handlers dom_xpath_object_handlers;
+#endif
 
 static HashTable classes;
 /* {{{ prop handler tables */
@@ -588,6 +591,9 @@ ZEND_GET_MODULE(dom)
 void dom_objects_free_storage(zend_object *object TSRMLS_DC);
 void dom_nnodemap_objects_free_storage(zend_object *object TSRMLS_DC);
 static void dom_nnodemap_object_dtor(zend_object *object TSRMLS_DC);
+#if defined(LIBXML_XPATH_ENABLED)
+void dom_xpath_objects_free_storage(zend_object *object TSRMLS_DC);
+#endif
 
 /* {{{ PHP_MINIT_FUNCTION(dom) */
 PHP_MINIT_FUNCTION(dom)
@@ -835,6 +841,10 @@ PHP_MINIT_FUNCTION(dom)
        REGISTER_DOM_CLASS(ce, "DOMStringExtend", NULL, php_dom_string_extend_class_functions, dom_string_extend_class_entry);
 
 #if defined(LIBXML_XPATH_ENABLED)
+       memcpy(&dom_xpath_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers));
+       dom_xpath_object_handlers.offset = XtOffsetOf(dom_xpath_object, std);
+       dom_xpath_object_handlers.free_obj = dom_xpath_objects_free_storage;
+
        INIT_CLASS_ENTRY(ce, "DOMXPath", php_dom_xpath_class_functions);
        ce.create_object = dom_xpath_objects_new;
        dom_xpath_class_entry = zend_register_internal_class_ex(&ce, NULL TSRMLS_CC);
@@ -997,9 +1007,9 @@ void node_list_unlink(xmlNodePtr node TSRMLS_DC)
 
 #if defined(LIBXML_XPATH_ENABLED)
 /* {{{ dom_xpath_objects_free_storage */
-void dom_xpath_objects_free_storage(void *object TSRMLS_DC)
+void dom_xpath_objects_free_storage(zend_object *object TSRMLS_DC)
 {
-       dom_xpath_object *intern = (dom_xpath_object *)object;
+       dom_xpath_object *intern = php_xpath_obj_from_obj(object);
 
        zend_object_std_dtor(&intern->std TSRMLS_CC);
 
@@ -1018,8 +1028,6 @@ void dom_xpath_objects_free_storage(void *object TSRMLS_DC)
                zend_hash_destroy(intern->node_list);
                FREE_HASHTABLE(intern->node_list);
        }
-
-       efree(object);
 }
 /* }}} */
 #endif
@@ -1052,9 +1060,9 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml
 {
        dom_nnodemap_object *mapptr = (dom_nnodemap_object *) intern->ptr;
 
-       if (basenode) {
-               GC_REFCOUNT(&basenode->std)++;
-       }
+       //??? if (basenode)
+       ZVAL_OBJ(&mapptr->baseobj_zv, &basenode->std);
+       Z_ADDREF(mapptr->baseobj_zv);
 
        mapptr->baseobj = basenode;
        mapptr->nodetype = ntype;
@@ -1066,12 +1074,9 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml
 
 static dom_object* dom_objects_set_class(zend_class_entry *class_type, zend_bool hash_copy TSRMLS_DC) /* {{{ */
 {
-       zend_class_entry *base_class;
-       size_t dom_object_size = instanceof_function(class_type, dom_xpath_class_entry TSRMLS_CC)
-               ? sizeof(dom_xpath_object) : sizeof(dom_object);
-       dom_object *intern = ecalloc(1, dom_object_size + sizeof(zval) * (class_type->default_properties_count - 1));
+       dom_object *intern = ecalloc(1, sizeof(dom_object) + sizeof(zval) * (class_type->default_properties_count - 1));
 
-       base_class = class_type;
+       zend_class_entry *base_class = class_type;
        while (base_class->type != ZEND_INTERNAL_CLASS && base_class->parent != NULL) {
                base_class = base_class->parent;
        }
@@ -1133,14 +1138,16 @@ zend_object *dom_objects_new(zend_class_entry *class_type TSRMLS_DC)
 /* {{{ zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC) */
 zend_object *dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC)
 {
-       dom_xpath_object *intern = (dom_xpath_object *) dom_objects_set_class(class_type, 1 TSRMLS_CC);
-       intern->registerPhpFunctions = 0;
-       intern->node_list = NULL;
+       dom_xpath_object *intern = ecalloc(1, sizeof(dom_xpath_object) + sizeof(zval) * (class_type->default_properties_count - 1));
 
        ALLOC_HASHTABLE(intern->registered_phpfunctions);
        zend_hash_init(intern->registered_phpfunctions, 0, NULL, ZVAL_PTR_DTOR, 0);
 
-       intern->std.handlers = dom_get_obj_handlers(TSRMLS_C);
+       intern->prop_handler = &dom_xpath_prop_handlers;
+       intern->std.handlers = &dom_xpath_object_handlers;
+
+       zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+       object_properties_init(&intern->std, class_type);
 
        return &intern->std;
 }
@@ -1162,8 +1169,8 @@ static void dom_nnodemap_object_dtor(zend_object *object TSRMLS_DC) /* {{{ */
                if (objmap->ns) {
                        xmlFree(objmap->ns);
                }
-               if (objmap->baseobj) {
-                       OBJ_RELEASE(&objmap->baseobj->std);
+               if (!ZVAL_IS_UNDEF(&objmap->baseobj_zv)) {
+                       zval_ptr_dtor(&objmap->baseobj_zv);
                }
                efree(objmap);
                intern->ptr = NULL;
@@ -1189,6 +1196,7 @@ zend_object *dom_nnodemap_objects_new(zend_class_entry *class_type TSRMLS_DC) /*
        intern = dom_objects_set_class(class_type, 1 TSRMLS_CC);
        intern->ptr = emalloc(sizeof(dom_nnodemap_object));
        objmap = (dom_nnodemap_object *)intern->ptr;
+       ZVAL_UNDEF(&objmap->baseobj_zv);
        objmap->baseobj = NULL;
        objmap->nodetype = 0;
        objmap->ht = NULL;
index 8f6eba12c0e7f7f04a9fd3b0345d2cd21cafd438..82ba681ff8fe599eabee7a06d0077e4067761ae0 100644 (file)
@@ -68,18 +68,24 @@ extern zend_module_entry dom_module_entry;
 #define DOM_NODESET XML_XINCLUDE_START
 
 typedef struct _dom_xpath_object {
-       zend_object  std;
        void *ptr;
        php_libxml_ref_obj *document;
        HashTable *prop_handler;
-       //??? zend_object_handle handle;
        int registerPhpFunctions;
        HashTable *registered_phpfunctions;
        HashTable *node_list;
+       zend_object std;
 } dom_xpath_object;
 
+static inline dom_xpath_object *php_xpath_obj_from_obj(zend_object *obj) {
+       return (dom_xpath_object*)((char*)(obj) - XtOffsetOf(dom_xpath_object, std));
+}
+
+#define Z_XPATHOBJ_P(zv)  php_xpath_obj_from_obj(Z_OBJ_P((zv)))
+
 typedef struct _dom_nnodemap_object {
        dom_object *baseobj;
+       zval baseobj_zv;
        int nodetype;
        xmlHashTable *ht;
        xmlChar *local;
index 21998704fe97fa2bd607ec30d5c75886e7f34499..de5f244b4df7509a902b6444a653c9a26ad45dbf 100644 (file)
@@ -196,7 +196,6 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs,
 
        if (!zend_make_callable(&fci.function_name, &callable TSRMLS_CC)) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable->val);
-               
        } else if (intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) { 
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'.", callable->val);
                /* Push an empty string, so that we at least have an xslt result... */
@@ -213,7 +212,7 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs,
                                }
                                GC_REFCOUNT(&retval)++;
                                zend_hash_next_index_insert(intern->node_list, &retval);
-                               obj = Z_DOMOBJ_P(&retval);
+                               obj = Z_XPATHOBJ_P(&retval);
                                nodep = dom_object_get_node(obj);
                                valuePush(ctxt, xmlXPathNewNodeSet(nodep));
                        } else if (Z_TYPE(retval) == IS_BOOL) {
@@ -223,12 +222,13 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs,
                                valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
                        } else {
                                convert_to_string_ex(&retval);
-                               valuePush(ctxt, xmlXPathNewString( Z_STRVAL(retval)));
+                               valuePush(ctxt, xmlXPathNewString(Z_STRVAL(retval)));
                        }
                        zval_ptr_dtor(&retval);
                }
        }
-       STR_FREE(callable);
+       STR_RELEASE(callable);
+       zval_dtor(&fci.function_name);
        if (fci.param_count > 0) {
                for (i = 0; i < nargs - 1; i++) {
                        zval_ptr_dtor(&fci.params[i]);
@@ -275,7 +275,7 @@ PHP_METHOD(domxpath, __construct)
                RETURN_FALSE;
        }
 
-       intern = Z_DOMOBJ_P(id);
+       intern = Z_XPATHOBJ_P(id);
        if (intern != NULL) {
                oldctx = (xmlXPathContextPtr)intern->ptr;
                if (oldctx != NULL) {
@@ -326,7 +326,7 @@ PHP_FUNCTION(dom_xpath_register_ns)
                return;
        }
 
-       intern = Z_DOMOBJ_P(id);
+       intern = Z_XPATHOBJ_P(id);
 
        ctxp = (xmlXPathContextPtr) intern->ptr;
        if (ctxp == NULL) {
@@ -343,13 +343,10 @@ PHP_FUNCTION(dom_xpath_register_ns)
 
 static void dom_xpath_iter(zval *baseobj, dom_object *intern) /* {{{ */
 {
-       dom_nnodemap_object *mapptr;
+       dom_nnodemap_object *mapptr = (dom_nnodemap_object *) intern->ptr;
 
-       mapptr = (dom_nnodemap_object *)intern->ptr;
-       Z_ADDREF_P(baseobj);
-       mapptr->baseobj = Z_OBJ_P(baseobj);
+       ZVAL_COPY_VALUE(&mapptr->baseobj_zv, baseobj);
        mapptr->nodetype = DOM_NODESET;
-
 }
 /* }}} */
 
@@ -371,7 +368,7 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
                return;
        }
 
-       intern = Z_DOMOBJ_P(id);
+       intern = Z_XPATHOBJ_P(id);
 
        ctxp = (xmlXPathContextPtr) intern->ptr;
        if (ctxp == NULL) {
@@ -522,7 +519,7 @@ PHP_FUNCTION(dom_xpath_register_php_functions)
        DOM_GET_THIS(id);
        
        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "a",  &array_value) == SUCCESS) {
-               intern = Z_DOMOBJ_P(id);
+               intern = Z_XPATHOBJ_P(id);
                zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
                while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(array_value)))) {
                        zend_string *str = zval_get_string(entry TSRMLS_CC);
@@ -535,13 +532,13 @@ PHP_FUNCTION(dom_xpath_register_php_functions)
                RETURN_TRUE;
 
        } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "S",  &name) == SUCCESS) {
-               intern = Z_DOMOBJ_P(id);
+               intern = Z_XPATHOBJ_P(id);
                
                ZVAL_LONG(&new_string, 1);
                zend_hash_update(intern->registered_phpfunctions, name, &new_string);
                intern->registerPhpFunctions = 2;
        } else {
-               intern = Z_DOMOBJ_P(id);
+               intern = Z_XPATHOBJ_P(id);
                intern->registerPhpFunctions = 1;
        }