chregu Sat Nov 29 11:37:38 2003 EDT
Modified files:
/php-src/ext/xsl php_xsl.c php_xsl.h xsltprocessor.c
Log:
Fixed for Bug #26384 (domxslt->process causes segfault with xsl:key)
Index: php-src/ext/xsl/php_xsl.c
diff -u php-src/ext/xsl/php_xsl.c:1.12 php-src/ext/xsl/php_xsl.c:1.13
--- php-src/ext/xsl/php_xsl.c:1.12 Sat Nov 29 08:31:51 2003
+++ php-src/ext/xsl/php_xsl.c Sat Nov 29 11:37:37 2003
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_xsl.c,v 1.12 2003/11/29 13:31:51 chregu Exp $ */
+/* $Id: php_xsl.c,v 1.13 2003/11/29 16:37:37 chregu Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -113,6 +113,7 @@
intern->ptr = NULL;
intern->prop_handler = NULL;
intern->parameter = NULL;
+ intern->hasKeys = 0;
ALLOC_HASHTABLE(intern->std.properties);
zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
@@ -145,6 +146,10 @@
xsltRegisterExtModuleFunction ((const xmlChar *) "function",
(const xmlChar *) "http://php.net/xsl",
xsl_ext_function_object_php);
+
+ REGISTER_LONG_CONSTANT("XSL_CLONE_AUTO", 0, CONST_CS |
CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XSL_CLONE_NEVER", -1, CONST_CS |
CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XSL_CLONE_ALWAYS", 1, CONST_CS |
CONST_PERSISTENT);
return SUCCESS;
}
Index: php-src/ext/xsl/php_xsl.h
diff -u php-src/ext/xsl/php_xsl.h:1.6 php-src/ext/xsl/php_xsl.h:1.7
--- php-src/ext/xsl/php_xsl.h:1.6 Fri Nov 28 17:08:13 2003
+++ php-src/ext/xsl/php_xsl.h Sat Nov 29 11:37:37 2003
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_xsl.h,v 1.6 2003/11/28 22:08:13 chregu Exp $ */
+/* $Id: php_xsl.h,v 1.7 2003/11/29 16:37:37 chregu Exp $ */
#ifndef PHP_XSL_H
#define PHP_XSL_H
@@ -54,7 +54,8 @@
void *ptr;
HashTable *prop_handler;
zend_object_handle handle;
- HashTable *parameter;
+ HashTable *parameter;
+ int hasKeys;
} xsl_object;
void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC);
@@ -72,8 +73,8 @@
RETURN_FALSE; \
}
-
-
+
+
PHP_MINIT_FUNCTION(xsl);
PHP_MSHUTDOWN_FUNCTION(xsl);
PHP_RINIT_FUNCTION(xsl);
Index: php-src/ext/xsl/xsltprocessor.c
diff -u php-src/ext/xsl/xsltprocessor.c:1.16 php-src/ext/xsl/xsltprocessor.c:1.17
--- php-src/ext/xsl/xsltprocessor.c:1.16 Fri Nov 21 07:21:35 2003
+++ php-src/ext/xsl/xsltprocessor.c Sat Nov 29 11:37:37 2003
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: xsltprocessor.c,v 1.16 2003/11/21 12:21:35 chregu Exp $ */
+/* $Id: xsltprocessor.c,v 1.17 2003/11/29 16:37:37 chregu Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -129,8 +129,11 @@
xsltStylesheetPtr sheetp, oldsheetp;
xsl_object *intern;
php_libxml_node_object *docobj;
- int prevSubstValue, prevExtDtdValue;
-
+ int prevSubstValue, prevExtDtdValue, clone_docu;
+ xmlNode *nodep;
+ zend_object_handlers *std_hnd;
+ zval *cloneDocu, *member;
+
DOM_GET_THIS(id);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
@@ -143,10 +146,10 @@
stylesheet document otherwise the node proxies will be a mess */
newdoc = xmlCopyDoc(doc, 1);
xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL);
-
prevSubstValue = xmlSubstituteEntitiesDefault(1);
prevExtDtdValue = xmlLoadExtDtdDefaultValue;
xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+
sheetp = xsltParseStylesheetDoc(newdoc);
xmlSubstituteEntitiesDefault(prevSubstValue);
xmlLoadExtDtdDefaultValue = prevExtDtdValue;
@@ -157,6 +160,28 @@
}
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+ std_hnd = zend_get_std_object_handlers();
+ MAKE_STD_ZVAL(member);
+ ZVAL_STRING(member, "cloneDocument", 0);
+ cloneDocu = std_hnd->read_property(id, member, 1 TSRMLS_CC);
+ convert_to_long(cloneDocu);
+ efree(member);
+ clone_docu = Z_LVAL_P(cloneDocu);
+ if (clone_docu == 0) {
+ /* check if the stylesheet is using xsl:key, if yes, we have to clone
the document _always_ before a transformation */
+ nodep = xmlDocGetRootElement(sheetp->doc)->children;
+ while (nodep) {
+ if (nodep->type == XML_ELEMENT_NODE &&
xmlStrEqual(nodep->name, "key") && xmlStrEqual(nodep->ns->href, XSLT_NAMESPACE)) {
+ intern->hasKeys = 1;
+ break;
+ }
+ nodep = nodep->next;
+ }
+ } else {
+ intern->hasKeys = clone_docu;
+ }
+
if ((oldsheetp = (xsltStylesheetPtr)intern->ptr)) {
/* free wrapper */
if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
@@ -181,7 +206,7 @@
xmlDoc *doc = NULL;
xmlDoc *newdocp;
xsltStylesheetPtr sheetp;
- int ret, clone = 0;
+ int ret, clone;
char **params = NULL;
xsl_object *intern;
php_libxml_node_object *docobj;
@@ -190,7 +215,7 @@
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
sheetp = (xsltStylesheetPtr) intern->ptr;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|l", &docp, &clone) ==
FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
RETURN_FALSE;
}
DOC_GET_OBJ(doc, docp, xmlDocPtr, docobj);
@@ -199,11 +224,11 @@
params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
}
- if (clone == 1) {
+ if (intern->hasKeys == 1) {
doc = xmlCopyDoc(doc, 1);
}
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**) params);
- if (clone == 1) {
+ if (intern->hasKeys == 1) {
xmlFreeDoc(doc);
}
@@ -233,7 +258,7 @@
xmlDoc *doc = NULL;
xmlDoc *newdocp;
xsltStylesheetPtr sheetp;
- int ret, uri_len, clone = 0;
+ int ret, uri_len, clone;
char **params = NULL, *uri;
xsl_object *intern;
php_libxml_node_object *docobj;
@@ -242,7 +267,7 @@
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
sheetp = (xsltStylesheetPtr) intern->ptr;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "os|l", &docp, &uri,
&uri_len, &clone) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "os", &docp, &uri,
&uri_len) == FAILURE) {
RETURN_FALSE;
}
@@ -252,13 +277,13 @@
params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
}
- if (clone == 1) {
+ if (intern->hasKeys == 1) {
doc = xmlCopyDoc(doc, 1);
}
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
- if (clone == 1) {
+ if (intern->hasKeys == 1) {
xmlFreeDoc(doc);
}
@@ -289,7 +314,7 @@
xmlDoc *doc = NULL;
xmlDoc *newdocp;
xsltStylesheetPtr sheetp;
- int ret, clone = 0;
+ int ret, clone;
xmlChar *doc_txt_ptr;
int doc_txt_len;
char **params = NULL;
@@ -300,7 +325,7 @@
intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
sheetp = (xsltStylesheetPtr) intern->ptr;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|l", &docp, &clone) ==
FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
RETURN_FALSE;
}
DOC_GET_OBJ(doc, docp, xmlDocPtr, docobj);
@@ -309,13 +334,13 @@
params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
}
- if (clone == 1) {
+ if (intern->hasKeys == 1) {
doc = xmlCopyDoc(doc, 1);
}
newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params);
- if (clone == 1) {
+ if (intern->hasKeys == 1) {
xmlFreeDoc(doc);
}
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php