]> granicus.if.org Git - php/commitdiff
Fix bug #27436 dom_import_simplexml innaccurate
authorRob Richards <rrichards@php.net>
Mon, 1 Mar 2004 12:09:24 +0000 (12:09 +0000)
committerRob Richards <rrichards@php.net>
Mon, 1 Mar 2004 12:09:24 +0000 (12:09 +0000)
extensions register callbacks to export nodes
prevents segfault passing invalid objects to import functions

ext/dom/php_dom.c
ext/libxml/libxml.c
ext/libxml/php_libxml.h
ext/simplexml/simplexml.c
ext/xsl/xsltprocessor.c

index 30bd8b818e0c0cb5f5c0df7cc991c7e5db962391..1163e61d4b9806a0cc907178c6c92ac0d559828d 100644 (file)
@@ -277,6 +277,20 @@ void dom_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
 }
 /* }}} */
 
+
+void *php_dom_export_node(zval *object TSRMLS_DC)
+{
+       php_libxml_node_object *intern;
+       xmlNodePtr nodep = NULL;
+
+       intern = (php_libxml_node_object *)zend_object_store_get_object(object TSRMLS_CC);
+       if (intern && intern->node) {
+               nodep = intern->node->node;
+       }
+
+       return nodep;   
+}
+
 /* {{{ proto somNode dom_import_simplexml(sxeobject node)
    Get a simplexml_element object from dom to allow for processing */
 PHP_FUNCTION(dom_import_simplexml)
@@ -284,7 +298,7 @@ PHP_FUNCTION(dom_import_simplexml)
 #ifdef HAVE_SIMPLEXML
        zval *rv = NULL;
        zval *node;
-       xmlNodePtr nodep;
+       xmlNodePtr nodep = NULL;
        php_libxml_node_object *nodeobj;
        int ret;
 
@@ -292,9 +306,10 @@ PHP_FUNCTION(dom_import_simplexml)
                return;
        }
 
-       NODE_GET_OBJ(nodep, node, xmlNodePtr, nodeobj);
+       nodeobj = (php_libxml_node_object *)zend_object_store_get_object(node TSRMLS_CC);
+       nodep = php_libxml_import_node(node TSRMLS_CC);
 
-       if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE) {
+       if (nodep && nodeobj && (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE)) {
                DOM_RET_OBJ(rv, (xmlNodePtr) nodep, &ret, (dom_object *)nodeobj);
        } else {
                php_error(E_WARNING, "Invalid Nodetype to import");
@@ -627,6 +642,8 @@ PHP_MINIT_FUNCTION(dom)
        REGISTER_LONG_CONSTANT("DOM_INVALID_ACCESS_ERR",        INVALID_ACCESS_ERR,             CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("DOM_VALIDATION_ERR",            VALIDATION_ERR,                 CONST_CS | CONST_PERSISTENT);
 
+       php_libxml_register_export(dom_node_class_entry, php_dom_export_node);
+
        return SUCCESS;
 }
 /* }}} */
index 148337ea4b18cebbb09e093538465ba865e30267..77a3df64a32f224cd2f4bc757aa94d3768d4a665 100644 (file)
 /* a true global for initialization */
 int _php_libxml_initialized = 0;
 
+typedef struct _php_libxml_func_handler {
+       php_libxml_export_node export_func;
+} php_libxml_func_handler;
+
+static HashTable php_libxml_exports;
+
 #ifdef ZTS
 int libxml_globals_id;
 #else
@@ -397,6 +403,8 @@ PHP_LIBXML_API void php_libxml_initialize() {
                /* report errors via handler rather than stderr */
                xmlSetGenericErrorFunc(NULL, php_libxml_error_handler);
 
+               zend_hash_init(&php_libxml_exports, 0, NULL, NULL, 1);
+
                _php_libxml_initialized = 1;
        }
 }
@@ -406,6 +414,7 @@ PHP_LIBXML_API void php_libxml_shutdown() {
                /* reset libxml generic error handling */
                xmlSetGenericErrorFunc(NULL, NULL);
                xmlCleanupParser();
+               zend_hash_destroy(&php_libxml_exports);
                _php_libxml_initialized = 0;
        }
 }
@@ -434,6 +443,7 @@ PHP_RINIT_FUNCTION(libxml)
 PHP_MSHUTDOWN_FUNCTION(libxml)
 {
        php_libxml_shutdown();
+
        return SUCCESS;
 }
 
@@ -474,7 +484,39 @@ PHP_FUNCTION(libxml_set_streams_context)
 }
 /* }}} */
 
+
 /* {{{ Common functions shared by extensions */
+int php_libxml_register_export(zend_class_entry *ce, php_libxml_export_node export_function)
+{
+       php_libxml_func_handler export_hnd;
+       
+       /* Initialize in case this module hasnt been loaded yet */
+       php_libxml_initialize();
+       export_hnd.export_func = export_function;
+
+    return zend_hash_add(&php_libxml_exports, ce->name, ce->name_length + 1, &export_hnd, sizeof(export_hnd), NULL);
+}
+
+PHP_LIBXML_API xmlNodePtr php_libxml_import_node(zval *object TSRMLS_DC)
+{
+       zend_class_entry *ce = NULL;
+       xmlNodePtr node = NULL;
+       php_libxml_func_handler *export_hnd;
+
+       if (object->type == IS_OBJECT) {
+               ce = Z_OBJCE_P(object);
+               while (ce->parent != NULL) {
+                       ce = ce->parent;
+               }
+               if (zend_hash_find(&php_libxml_exports, ce->name, ce->name_length + 1, (void **) &export_hnd)  == SUCCESS) {
+                       node = export_hnd->export_func(object TSRMLS_CC);
+               }
+    }
+
+       return node;
+
+}
+
 int php_libxml_increment_node_ptr(php_libxml_node_object *object, xmlNodePtr node, void *private_data TSRMLS_DC)
 {
        int ret_refcount = -1;
index d1c6b86903bebbf2e8e7ab71cdac3ee42db7442c..ab47e202fb46c7df591eef004e816c849b02a848 100644 (file)
@@ -64,11 +64,15 @@ typedef struct _php_libxml_node_object {
        HashTable *properties;
 } php_libxml_node_object;
 
+typedef void * (*php_libxml_export_node) (zval *object TSRMLS_DC);
+
 PHP_FUNCTION(libxml_set_streams_context);
 int php_libxml_increment_node_ptr(php_libxml_node_object *object, xmlNodePtr node, void *private_data TSRMLS_DC);
 int php_libxml_decrement_node_ptr(php_libxml_node_object *object TSRMLS_DC);
 int php_libxml_increment_doc_ref(php_libxml_node_object *object, xmlDocPtr docp TSRMLS_DC);
 int php_libxml_decrement_doc_ref(php_libxml_node_object *object TSRMLS_DC);
+PHP_LIBXML_API xmlNodePtr php_libxml_import_node(zval *object TSRMLS_DC);
+PHP_LIBXML_API int php_libxml_register_export(zend_class_entry *ce, php_libxml_export_node export_function);
 /* When an explicit freeing of node and children is required */
 void php_libxml_node_free_resource(xmlNodePtr node TSRMLS_DC);
 /* When object dtor is called as node may still be referenced */
index 6cc3e23e1e789a5cb386025351512735b39e3f29..f232c97c2084a3d982e59dbbe7d979f9d012e96d 100644 (file)
@@ -1490,6 +1490,16 @@ static void php_sxe_iterator_rewind(zend_object_iterator *iter TSRMLS_DC)
 }
 
 
+void *simplexml_export_node(zval *object TSRMLS_DC)
+{
+       php_sxe_object *sxe;
+       xmlNodePtr node;
+
+       sxe = php_sxe_fetch_object(object TSRMLS_CC);
+       GET_NODE(sxe, node);
+       return php_sxe_get_first_node(sxe, node TSRMLS_CC);     
+}
+
 #ifdef HAVE_DOM
 /* {{{ proto simplemxml_element simplexml_import_dom(domNode node [, string class_name])
    Get a simplexml_element object from dom to allow for processing */
@@ -1509,8 +1519,9 @@ PHP_FUNCTION(simplexml_import_dom)
 
        object = (php_libxml_node_object *)zend_object_store_get_object(node TSRMLS_CC);
 
-       if (object->node && object->node->node) {
-               nodep = object->node->node;
+       nodep = php_libxml_import_node(node TSRMLS_CC);
+
+       if (nodep) {
                if (nodep->doc == NULL) {
                        php_error(E_WARNING, "Imported Node must have associated Document");
                        RETURN_NULL();
@@ -1603,6 +1614,8 @@ PHP_MINIT_FUNCTION(simplexml)
        }
 #endif /* HAVE_SPL */
 
+       php_libxml_register_export(sxe_class_entry, simplexml_export_node);
+
        return SUCCESS;
 }
 /* }}} */
index 37358d01bec6b3d9f2b96c47b37a6ca6cdd8d469..4187b6760c3e0af7a68880f68bfc1d1c235c68f2 100644 (file)
@@ -296,19 +296,24 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
        xmlDoc *doc = NULL, *newdoc = NULL;
        xsltStylesheetPtr sheetp, oldsheetp;
        xsl_object *intern;
-       php_libxml_node_object *docobj;
        int prevSubstValue, prevExtDtdValue, clone_docu = 0;
-       xmlNode *nodep;
+       xmlNode *nodep = NULL;
        zend_object_handlers *std_hnd;
        zval *cloneDocu, *member;
-
-       DOM_GET_THIS(id);
        
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
+       if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oo", &id, xsl_xsltprocessor_class_entry, &docp) == FAILURE) {
                RETURN_FALSE;
        }
 
-       DOC_GET_OBJ(doc, docp, xmlDocPtr, docobj);
+       nodep = php_libxml_import_node(docp TSRMLS_CC);
+       
+       if (nodep) {
+               doc = nodep->doc;
+       }
+       if (doc == NULL) {
+               php_error(E_WARNING, "Invalid Document");
+               RETURN_NULL();
+       }
 
        /* libxslt uses _private, so we must copy the imported 
        stylesheet document otherwise the node proxies will be a mess */