diff options
author | Christian Stocker <chregu@php.net> | 2004-07-28 12:40:53 +0000 |
---|---|---|
committer | Christian Stocker <chregu@php.net> | 2004-07-28 12:40:53 +0000 |
commit | 5f888422d987ebcac1ec03484e62d225f6989c8b (patch) | |
tree | ea5f1339824df3f3fa7a1b6876d2c1ba279a0238 /ext/xsl | |
parent | 3d9eeb4538cb9c901362729d7a03749730ada251 (diff) | |
download | php-git-5f888422d987ebcac1ec03484e62d225f6989c8b.tar.gz |
Fix for bug #29409 (Segfault in PHP functions called from XSLT). (by Rob)
Diffstat (limited to 'ext/xsl')
-rw-r--r-- | ext/xsl/php_xsl.c | 6 | ||||
-rw-r--r-- | ext/xsl/php_xsl.h | 1 | ||||
-rw-r--r-- | ext/xsl/xsltprocessor.c | 144 |
3 files changed, 71 insertions, 80 deletions
diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c index ff62618ff8..18df25fff1 100644 --- a/ext/xsl/php_xsl.c +++ b/ext/xsl/php_xsl.c @@ -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); diff --git a/ext/xsl/php_xsl.h b/ext/xsl/php_xsl.h index bd71315932..7d9258feca 100644 --- a/ext/xsl/php_xsl.h +++ b/ext/xsl/php_xsl.h @@ -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); diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index a331df7df6..540fe0af80 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -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) { |