]> granicus.if.org Git - php/commitdiff
Fix for bug #29409 (Segfault in PHP functions called from XSLT). (by Rob)
authorChristian Stocker <chregu@php.net>
Wed, 28 Jul 2004 12:40:53 +0000 (12:40 +0000)
committerChristian Stocker <chregu@php.net>
Wed, 28 Jul 2004 12:40:53 +0000 (12:40 +0000)
NEWS
ext/xsl/php_xsl.c
ext/xsl/php_xsl.h
ext/xsl/xsltprocessor.c

diff --git a/NEWS b/NEWS
index 72f3b415abb24c14e7b17c3df86264aa31481a4d..7f7f37fbe6c655896fecbbf925c0a9b11cd65bde 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2004, PHP 5.1.0
+- Fixed bug #29409 (Segfault in PHP functions called from XSLT). (Rob)
 - Fixed bug #29335 (fetch functions now use MYSQLI_BOTH as default) (Georg)
 - Fixed bug #29311 (calling parent constructor in mysqli). (Georg)
 - Fixed bug #29236 (memory error when wsdl-cache is enabled). (Dmitry)
index ff62618ff875f61b4f09c9670c6286d5479c2d05..18df25fff1bf23af9e54dda493bd7999fba3787e 100644 (file)
@@ -132,6 +132,11 @@ void xsl_objects_free_storage(void *object TSRMLS_DC)
        zend_hash_destroy(intern->parameter);
        FREE_HASHTABLE(intern->parameter);
        
+       if (intern->node_list) {
+               zend_hash_destroy(intern->node_list);
+               FREE_HASHTABLE(intern->node_list);
+       }
+
        if (intern->ptr) {
                /* free wrapper */
                if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
@@ -160,6 +165,7 @@ zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC)
        intern->parameter = NULL;
        intern->hasKeys = 0;
        intern->registerPhpFunctions = 0;
+       intern->node_list = NULL;
 
        ALLOC_HASHTABLE(intern->std.properties);
        zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
index bd71315932ef13f805d1b98f64392c34611c664b..7d9258fecadc06577853294b8d0ecb2c99f31472 100644 (file)
@@ -57,6 +57,7 @@ typedef struct _xsl_object {
        HashTable *parameter;
        int hasKeys;
        int registerPhpFunctions;
+       HashTable *node_list;
 } xsl_object;
 
 void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC);
index a331df7df66643904e5cbf966ddc69e5037ef227..540fe0af80ed091f8b841cc6e182fec704494cae 100644 (file)
@@ -144,6 +144,7 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t
        xmlXPathObjectPtr obj;
        char *str;
        char *callable = NULL;
+       xsl_object *intern;
        
        TSRMLS_FETCH();
 
@@ -258,6 +259,13 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t
                        if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) {
                                xmlNode *nodep;
                                dom_object *obj;
+                               intern = (xsl_object *) tctxt->_private;
+                               if (intern->node_list == NULL) {
+                                       ALLOC_HASHTABLE(intern->node_list);
+                                       zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
+                               }
+                               zval_add_ref(&retval);
+                               zend_hash_next_index_insert(intern->node_list, &retval, sizeof(zval *), NULL);
                                obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC);
                                nodep = dom_object_get_node(obj);
                                valuePush(ctxt, xmlXPathNewNodeSet(nodep));
@@ -378,6 +386,55 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
 /* }}} end xsl_xsltprocessor_import_stylesheet */
 
 
+static xmlDocPtr php_xsl_apply_stylesheet(xsl_object *intern, xsltStylesheetPtr style, xmlDocPtr doc TSRMLS_DC)
+{
+       xmlDocPtr newdocp;
+       xsltTransformContextPtr ctxt;
+       char **params = NULL;
+       int clone;
+
+
+       if (intern->parameter) {
+               params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
+       }
+
+       if (intern->hasKeys == 1) {
+               doc = xmlCopyDoc(doc, 1);
+       }
+
+       ctxt = xsltNewTransformContext(style, doc);
+       ctxt->_private = (void *) intern;
+       
+       newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params, NULL, NULL, ctxt);
+
+       xsltFreeTransformContext(ctxt);
+
+       if (intern->node_list != NULL) {
+               zend_hash_destroy(intern->node_list);
+               FREE_HASHTABLE(intern->node_list);      
+               intern->node_list = NULL;
+       }
+
+       if (intern->registerPhpFunctions == 1) {
+               php_xsl_unregister_php_functions();
+       }
+       
+       if (intern->hasKeys == 1) {
+               xmlFreeDoc(doc);
+       }
+
+       if (params) {
+               clone = 0;
+               while(params[clone]) {
+                       efree(params[clone++]);
+               }
+               efree(params);
+       }
+
+       return newdocp;
+
+}
+
 /* {{{ proto xsl_document xsl_xsltprocessor_transform_to_doc(node doc [,boolean clone]);
 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
 Since: 
@@ -389,8 +446,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
        xmlNodePtr node = NULL;
        xmlDoc *newdocp;
        xsltStylesheetPtr sheetp;
-       int ret, clone;
-       char **params = NULL;
+       int ret;
        xsl_object *intern;
        
        id = getThis();
@@ -411,30 +467,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
                RETURN_NULL();
        }
 
-       if (intern->parameter) {
-               params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
-       }
-
-       if (intern->hasKeys == 1) {
-               doc = xmlCopyDoc(doc, 1);
-       }
-       newdocp = xsltApplyStylesheet(sheetp, doc, (const char**) params);
-       
-       if (intern->registerPhpFunctions == 1) {
-               php_xsl_unregister_php_functions();
-       }
-       
-       if (intern->hasKeys == 1) {
-               xmlFreeDoc(doc);
-       }
-
-       if (params) {
-               clone = 0;
-               while(params[clone]) {
-                       efree(params[clone++]);
-               }
-               efree(params);
-       }
+       newdocp = php_xsl_apply_stylesheet(intern, sheetp, doc TSRMLS_CC);
 
        if (newdocp) {
                DOM_RET_OBJ(rv, (xmlNodePtr) newdocp, &ret, NULL);
@@ -455,8 +488,8 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
        xmlDoc *newdocp;
        xmlNodePtr node = NULL;
        xsltStylesheetPtr sheetp;
-       int ret, uri_len, clone;
-       char **params = NULL, *uri;
+       int ret, uri_len;
+       char *uri;
        xsl_object *intern;
        
        id = getThis();
@@ -477,31 +510,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
                RETURN_NULL();
        }
 
-       if (intern->parameter) {
-               params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
-       }
-
-       if (intern->hasKeys == 1) {
-               doc = xmlCopyDoc(doc, 1);
-       }
-
-       newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
-       
-       if (intern->registerPhpFunctions == 1) {
-               php_xsl_unregister_php_functions();
-       }
-       
-       if (intern->hasKeys == 1) {
-               xmlFreeDoc(doc);
-       }
-
-       if (params) {
-               clone = 0;
-               while(params[clone]) {
-                       efree(params[clone++]);
-               }
-               efree(params);
-       }
+       newdocp = php_xsl_apply_stylesheet(intern, sheetp, doc TSRMLS_CC);
 
        ret = -1;
        if (newdocp) {
@@ -523,10 +532,9 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
        xmlDoc *newdocp;
        xmlNodePtr node = NULL;
        xsltStylesheetPtr sheetp;
-       int ret, clone;
+       int ret;
        xmlChar *doc_txt_ptr;
        int doc_txt_len;
-       char **params = NULL;
        xsl_object *intern;
        
        id = getThis();
@@ -547,31 +555,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
                RETURN_NULL();
        }
 
-       if (intern->parameter) {
-               params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
-       }
-
-       if (intern->hasKeys == 1) {
-               doc = xmlCopyDoc(doc, 1);
-       }
-
-       newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
-       
-       if (intern->registerPhpFunctions == 1) {
-               php_xsl_unregister_php_functions();
-       }
-       
-       if (intern->hasKeys == 1) {
-               xmlFreeDoc(doc);
-       }
-
-       if (params) {
-               clone = 0;
-               while(params[clone]) {
-                       efree(params[clone++]);
-               }
-               efree(params);
-       }
+       newdocp = php_xsl_apply_stylesheet(intern, sheetp, doc TSRMLS_CC);
 
        ret = -1;
        if (newdocp) {