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

Reply via email to