rrichards               Wed Sep 17 15:34:43 2003 EDT

  Modified files:              (Branch: PHP_4_3)
    /php-src/ext/domxml php_domxml.c 
  Log:
  fix some threading issues
  fix mem leaks in append_child with attribute nodes
  
Index: php-src/ext/domxml/php_domxml.c
diff -u php-src/ext/domxml/php_domxml.c:1.218.2.31 
php-src/ext/domxml/php_domxml.c:1.218.2.32
--- php-src/ext/domxml/php_domxml.c:1.218.2.31  Tue Sep  9 15:43:44 2003
+++ php-src/ext/domxml/php_domxml.c     Wed Sep 17 15:34:42 2003
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_domxml.c,v 1.218.2.31 2003/09/09 19:43:44 msopacua Exp $ */
+/* $Id: php_domxml.c,v 1.218.2.32 2003/09/17 19:34:42 rrichards Exp $ */
 
 /* TODO
  * - Support Notation Nodes
@@ -146,6 +146,8 @@
 #define DOMXML_LOAD_SUBSTITUTE_ENTITIES 4
 #define DOMXML_LOAD_COMPLETE_ATTRS 8
 #define DOMXML_LOAD_DONT_KEEP_BLANKS 16
+#define DOMXML_LOAD_FILE 1
+
 static int le_domxmldocp;
 static int le_domxmldoctypep;
 static int le_domxmldtdp;
@@ -170,7 +172,6 @@
 static void domxml_error(void *ctx, const char *msg, ...);
 static void domxml_error_ext(void *ctx, const char *msg, ...);
 static void domxml_error_validate(void *ctx, const char *msg, ...);
-static xmlDocPtr php_dom_xmlSAXParse(xmlSAXHandlerPtr sax, const char *buffer, int 
size, int recovery, void *data);
 
 #if defined(LIBXML_XPATH_ENABLED)
 static int le_xpathctxp;
@@ -1477,73 +1478,13 @@
        
 }
 
-static xmlDocPtr php_dom_xmlSAXParse(xmlSAXHandlerPtr sax, const char *buffer, int 
size, int recovery, void *data)
-{
-    xmlDocPtr ret;
-    xmlParserCtxtPtr ctxt;
-    domxml_ErrorCtxt errorCtxt;
-    char *directory = NULL;
-    
-    xmlInitParser();
-    /*if size == -1, we assume, it's a filename not a inmemory xml doc*/
-    if (size == -1) {
-               ctxt = (xmlParserCtxt *) xmlCreateFileParserCtxt( buffer);
-    } else {
-               ctxt = (xmlParserCtxt *) xmlCreateMemoryParserCtxt((xmlChar *) buffer, 
size);
-    }
-    if (ctxt == NULL) {
-               return(NULL);
-    }
-       if (sax != NULL) {
-               if (ctxt->sax != NULL)
-                       xmlFree(ctxt->sax);
-               ctxt->sax = sax;
-       }
-       if (data!=NULL) {
-               ctxt->_private=data;
-       }
-
-    /* store directory name */
-       if (size == -1) {
-           if ((ctxt->directory == NULL) && (directory == NULL))
-           directory = xmlParserGetDirectory(buffer);
-           if ((ctxt->directory == NULL) && (directory != NULL))
-           ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
-       }
-       errorCtxt.valid = &ctxt->vctxt;
-       errorCtxt.errors = data;
-       errorCtxt.parser = ctxt;   
-
-       ctxt->sax->error = domxml_error_ext;
-       ctxt->sax->warning = domxml_error_ext;
-       ctxt->vctxt.userData= (void *) &errorCtxt;
-       ctxt->vctxt.error    = (xmlValidityErrorFunc) domxml_error_validate;
-       ctxt->vctxt.warning  = (xmlValidityWarningFunc) domxml_error_validate; 
-
-       xmlParseDocument(ctxt);
-
-       if ((ctxt->wellFormed) || recovery) {
-               ret = ctxt->myDoc;
-       } else {
-               ret = NULL;
-               xmlFreeDoc(ctxt->myDoc);
-               ctxt->myDoc = NULL;
-       }
-    if (sax != NULL)
-        ctxt->sax = NULL;
-
-       xmlFreeParserCtxt(ctxt);
-    
-       return(ret);
-}
-
 PHP_MSHUTDOWN_FUNCTION(domxml)
 {
 #if HAVE_DOMXSLT
        xsltCleanupGlobals();
 #endif
        xmlCleanupParser();
-       
+
 /*     If you want do find memleaks in this module, compile libxml2 with 
--with-mem-debug and
        uncomment the following line, this will tell you the amount of not freed memory
        and the total used memory into apaches error_log  */
@@ -2472,20 +2413,37 @@
                                foundattrp = xmlHasProp(parent, child->name);
                        else
                                foundattrp = xmlHasNsProp(parent, child->name, 
child->ns->href);
-                       if ((foundattrp != NULL) && (foundattrp != (xmlAttrPtr) 
child)) {
-                               xmlUnlinkNode((xmlNodePtr) foundattrp);
-                               (void)xmlCopyProp(parent, (xmlAttrPtr) child);
-                               /* We're in the dark here, what happened to the 
parent, let's
-                                * assume it's handled properly and return the new(?) 
parent
-                                */
-                               new_child = parent;
+                       if (foundattrp != (xmlAttrPtr) child) {
+                               if (foundattrp != NULL) {
+                                       if (dom_object_get_data((xmlNodePtr) 
foundattrp) == NULL) {
+                                               node_list_unlink(foundattrp->children);
+                                               xmlUnlinkNode((xmlNodePtr) foundattrp);
+                                               xmlFreeProp(foundattrp);
+                                       } else {
+                                               xmlUnlinkNode((xmlNodePtr) foundattrp);
+                                       }
+                                       new_child = (xmlNodePtr) xmlCopyProp(parent, 
(xmlAttrPtr) child);
+                                       if (!new_child) {
+                                               php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "No such attribute '%s'", child->name);
+                                               RETURN_FALSE;
+                                       } else {
+                                               xmlAttr *prop;
+                                               prop = parent->properties;
+                                               while (prop->next != NULL) {
+                                                       prop = prop->next;
+                                               }
+                                               prop->next = (xmlAttrPtr) new_child;
+                                               ((xmlAttrPtr) new_child)->prev = prop;
+                                       }
+                               }
+                       } else {
+                               new_child = (xmlNodePtr) foundattrp;
                        }
                }
                /* For all other intents and purposes fall through to the xmlAddChild
                 * call
                 */
        }
-
        
        if (NULL == new_child) {
                new_child = xmlAddChild(parent, child);
@@ -3950,6 +3908,82 @@
 }
 /* }}} */
 
+static xmlDocPtr domxml_document_parser(int mode, int loadtype, char *source, void 
*data TSRMLS_DC) {
+    xmlDocPtr ret;
+    xmlParserCtxtPtr ctxt;
+       domxml_ErrorCtxt errorCtxt;
+       char *directory = NULL;
+       int validate = 0, resolve_externals = 0;
+       int keep_blanks = 1, recovery = 1, substitute_ent;
+
+       substitute_ent = xmlSubstituteEntitiesDefaultValue;
+
+       if (mode & DOMXML_LOAD_DONT_KEEP_BLANKS) 
+               keep_blanks  =  0;
+
+       if(mode & DOMXML_LOAD_SUBSTITUTE_ENTITIES)
+               substitute_ent = 1;
+
+       if(mode & DOMXML_LOAD_COMPLETE_ATTRS)
+               resolve_externals = XML_COMPLETE_ATTRS;
+
+       if(mode & DOMXML_LOAD_VALIDATING)
+               validate = 1;
+
+       if(mode & DOMXML_LOAD_RECOVERING)
+               recovery = 1;
+
+       xmlInitParser();
+
+       if (loadtype == DOMXML_LOAD_FILE) {
+               ctxt = xmlCreateFileParserCtxt(source);
+       } else {
+               ctxt = xmlCreateDocParserCtxt(source);
+       }
+
+       if (ctxt == NULL) {
+               return(NULL);
+       }
+
+       if (loadtype == DOMXML_LOAD_FILE) {
+               if ((ctxt->directory == NULL) && (directory == NULL))
+                       directory = xmlParserGetDirectory(source);
+               if ((ctxt->directory == NULL) && (directory != NULL))
+                       ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
+       }
+
+       ctxt->validate = validate;
+       ctxt->loadsubset = resolve_externals;
+       ctxt->keepBlanks = keep_blanks;
+       ctxt->replaceEntities = substitute_ent;
+
+       if (data != NULL) {
+               errorCtxt.valid = &ctxt->vctxt;
+               errorCtxt.errors = data;
+               errorCtxt.parser = ctxt;   
+
+               ctxt->sax->error = domxml_error_ext;
+               ctxt->sax->warning = domxml_error_ext;
+               ctxt->vctxt.userData= (void *) &errorCtxt;
+               ctxt->vctxt.error    = (xmlValidityErrorFunc) domxml_error_validate;
+               ctxt->vctxt.warning  = (xmlValidityWarningFunc) domxml_error_validate;
+       }
+
+       xmlParseDocument(ctxt);
+
+       if (ctxt->wellFormed || recovery)
+               ret = ctxt->myDoc;
+       else {
+               ret = NULL;
+               xmlFreeDoc(ctxt->myDoc);
+               ctxt->myDoc = NULL;
+       }
+
+       xmlFreeParserCtxt(ctxt);
+
+       return(ret);
+}
+
 /* {{{ proto object xmldoc(string xmldoc[, int mode[, array error]])
    Creates DOM object of XML document */
 PHP_FUNCTION(xmldoc)
@@ -3960,76 +3994,23 @@
        char *buffer;
        int buffer_len;
        long mode = 0;
-       int prevSubstValue;
-       int oldvalue =  xmlDoValidityCheckingDefaultValue;
-       int oldvalue_keepblanks;
-       int prevLoadExtDtdValue = xmlLoadExtDtdDefaultValue;
        zval *errors ;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz", &buffer, 
&buffer_len, &mode, &errors) == FAILURE) {
                return;
        }
-/*     Either of the following line force validation */
-/*     xmlLoadExtDtdDefaultValue = XML_DETECT_IDS; */
-/*     xmlDoValidityCheckingDefaultValue = 1; */
-       if (ZEND_NUM_ARGS() == 3 ) {
+
+       if (ZEND_NUM_ARGS() == 3) {
                zval_dtor(errors);
                array_init(errors);
+               docp = domxml_document_parser(mode, 0, buffer, errors TSRMLS_CC);
+       } else {
+               docp = domxml_document_parser(mode, 0, buffer, NULL TSRMLS_CC);
        }
-        
-       if (mode & DOMXML_LOAD_DONT_KEEP_BLANKS) 
-               oldvalue_keepblanks  =  xmlKeepBlanksDefault(0);
-       else 
-               oldvalue_keepblanks  =  xmlKeepBlanksDefault(1);
-
-       if(mode & DOMXML_LOAD_SUBSTITUTE_ENTITIES)
-               prevSubstValue = xmlSubstituteEntitiesDefault (1);
-       else
-               prevSubstValue = xmlSubstituteEntitiesDefault (0);
-
-       if(mode & DOMXML_LOAD_COMPLETE_ATTRS)
-               xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
-
-       switch (mode & (DOMXML_LOAD_PARSING | DOMXML_LOAD_VALIDATING | 
DOMXML_LOAD_RECOVERING)) {
-               case DOMXML_LOAD_PARSING:
-                       xmlDoValidityCheckingDefaultValue = 0;
-                       if (ZEND_NUM_ARGS() == 3) {
-                               docp = php_dom_xmlSAXParse( NULL, (char *) buffer, 
buffer_len, 0 , errors);
-                       } else {
-                               docp = xmlParseDoc(buffer);
-                       }
-                       break;
-               case DOMXML_LOAD_VALIDATING:
-                       xmlDoValidityCheckingDefaultValue = 1;
-                       if (ZEND_NUM_ARGS() == 3) {
-                               docp = php_dom_xmlSAXParse(NULL, (char *) buffer, 
buffer_len, 0, errors);
-                       } else {
-                               docp = xmlParseDoc(buffer);
-                       }
-                       break;
-               case DOMXML_LOAD_RECOVERING:
-                       xmlDoValidityCheckingDefaultValue = 0;
-                       if (ZEND_NUM_ARGS() == 3) {
-                               docp = php_dom_xmlSAXParse(NULL, (char *) buffer, 
buffer_len, 1, errors);
-                       } else {
-                               docp = xmlRecoverDoc(buffer);
-                       }
-                       break;
-       }
-       xmlSubstituteEntitiesDefault (prevSubstValue);
-       xmlDoValidityCheckingDefaultValue = oldvalue;
-       xmlLoadExtDtdDefaultValue = prevLoadExtDtdValue;
-       xmlKeepBlanksDefault(oldvalue_keepblanks);
 
        if (!docp)
                RETURN_FALSE;
 
-/*     dtd = xmlGetIntSubset(docp);
-       if(dtd) {
-               xmlParseDTD(dtd->ExternalID, dtd->SystemID);
-       }
-*/
-
        if(DOMXML_IS_TYPE(getThis(), domxmldoc_class_entry)) {
                DOMXML_DOMOBJ_NEW(getThis(), (xmlNodePtr) docp, &ret);
        } else {
@@ -4047,68 +4028,24 @@
        int ret, file_len;
        char *file;
        long mode = 0;
-       int prevSubstValue;
-       int oldvalue =  xmlDoValidityCheckingDefaultValue;
-       int oldvalue_keepblanks;
        zval *errors = NULL;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz", &file, &file_len, 
&mode,  &errors) == FAILURE) {
                return;
        }
-                       
-       if (ZEND_NUM_ARGS() == 3 ) {
+
+       if (ZEND_NUM_ARGS() == 3) {
                zval_dtor(errors);
                array_init(errors);
+               docp = domxml_document_parser(mode, 1, file, errors TSRMLS_CC);
+       } else {
+               docp = domxml_document_parser(mode, 1, file, NULL TSRMLS_CC);
        }
-        
-       if (mode & DOMXML_LOAD_DONT_KEEP_BLANKS) 
-               oldvalue_keepblanks  =  xmlKeepBlanksDefault(0);
-       else 
-               oldvalue_keepblanks  =  xmlKeepBlanksDefault(1);
-
-       if(mode & DOMXML_LOAD_SUBSTITUTE_ENTITIES)
-               prevSubstValue = xmlSubstituteEntitiesDefault (1);
-       else
-               prevSubstValue = xmlSubstituteEntitiesDefault (0);
-
-       if(mode & DOMXML_LOAD_COMPLETE_ATTRS)
-               xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
-
-       switch (mode & (DOMXML_LOAD_PARSING | DOMXML_LOAD_VALIDATING | 
DOMXML_LOAD_RECOVERING)) {
-               case DOMXML_LOAD_PARSING:
-                       xmlDoValidityCheckingDefaultValue = 0;
-                       if (ZEND_NUM_ARGS() == 3) {
-                               docp = php_dom_xmlSAXParse( NULL, (char *) file, -1 , 
0 , errors);
-                       } else {
-                               docp = xmlParseFile(file);
-                       }
-                       break;
-               case DOMXML_LOAD_VALIDATING:
-                       xmlDoValidityCheckingDefaultValue = 1;
-                       if (ZEND_NUM_ARGS() == 3) {
-                               docp = php_dom_xmlSAXParse(NULL, (char *) file, -1, 0, 
errors);
-                       } else {
-                               docp = xmlParseFile(file);
-                       }
-                       break;
-               case DOMXML_LOAD_RECOVERING:
-                       xmlDoValidityCheckingDefaultValue = 0;
-                       if (ZEND_NUM_ARGS() == 3) {
-                               docp = php_dom_xmlSAXParse(NULL, (char*) file, -1, 1, 
errors);
-                       } else {
-                               docp = xmlRecoverFile(file);
-                       }
-                       break;
-       }
-       xmlSubstituteEntitiesDefault (prevSubstValue);
-       xmlDoValidityCheckingDefaultValue = oldvalue;
-       xmlKeepBlanksDefault(oldvalue_keepblanks);
 
        if (!docp) {
                RETURN_FALSE;
        }
 
-
        if(DOMXML_IS_TYPE(getThis(), domxmldoc_class_entry)) {
                DOMXML_DOMOBJ_NEW(getThis(), (xmlNodePtr) docp, &ret);
        } else {
@@ -4303,7 +4240,6 @@
        xmlDoc *docp;
        domxml_ErrorCtxt errorCtxt;
        zval *errors ;
-       int oldvalue =  xmlDoValidityCheckingDefaultValue;
            
        DOMXML_PARAM_ONE(docp, id, le_domxmldocp,"|z",&errors);
        errorCtxt.valid = &cvp;
@@ -4317,7 +4253,6 @@
        }
 
        errorCtxt.parser = NULL;
-       xmlDoValidityCheckingDefaultValue = 1;
        cvp.userData = (void *) &errorCtxt;
        cvp.error    = (xmlValidityErrorFunc) domxml_error_validate;
        cvp.warning  = (xmlValidityWarningFunc) domxml_error_validate;
@@ -4330,8 +4265,6 @@
        } else {
                RETVAL_FALSE;
        }
-       xmlDoValidityCheckingDefaultValue = oldvalue;
-    
 }
 /* }}} */
 
@@ -4443,7 +4376,7 @@
        char *tagname;
        int tagname_len;
        char **atts = NULL;
-               
+
        DOMXML_PARAM_THREE(parserp, id, le_domxmlparserp,"s|a", &tagname, 
&tagname_len, &params);
        if (params != NULL) {
                atts = php_xmlparser_make_params(params TSRMLS_CC);
@@ -4838,7 +4771,8 @@
        }
 
        /* Create a new xml document */
-       docp = xmlParseDoc(buf);
+       docp = domxml_document_parser(0, 0, buf, NULL TSRMLS_CC);
+
        if (!docp) {
                RETURN_FALSE;
        }
@@ -5180,28 +5114,26 @@
        zval *rv;
        xmlDocPtr docp;
        xsltStylesheetPtr sheetp;
-       int ret;
+       int ret, mode, prevSubstValue, prevExtDtdValue;
        char *buffer;
        int buffer_len;
-       int prevSubstValue, prevExtDtdValue;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buffer, 
&buffer_len) == FAILURE) {
                RETURN_FALSE;
        }
 
-       prevSubstValue = xmlSubstituteEntitiesDefault (1);
-       prevExtDtdValue = xmlLoadExtDtdDefaultValue;
-       xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
-
-       docp = xmlParseDoc(buffer);
-
-       xmlSubstituteEntitiesDefault (prevSubstValue);
-       xmlLoadExtDtdDefaultValue = prevExtDtdValue;
+       mode = DOMXML_LOAD_SUBSTITUTE_ENTITIES | DOMXML_LOAD_COMPLETE_ATTRS;
+       docp = domxml_document_parser(mode, 0, buffer, NULL TSRMLS_CC);
 
        if (!docp)
                RETURN_FALSE;
 
+       prevSubstValue = xmlSubstituteEntitiesDefault(1);
+       prevExtDtdValue = xmlLoadExtDtdDefaultValue;
+       xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
        sheetp = xsltParseStylesheetDoc(docp);
+       xmlSubstituteEntitiesDefault(prevSubstValue);
+       xmlLoadExtDtdDefaultValue = prevExtDtdValue;
 
        if (!sheetp) {
                xmlFreeDoc(docp);
@@ -5250,26 +5182,32 @@
 PHP_FUNCTION(domxml_xslt_stylesheet_file)
 {
        zval *rv;
+       xmlDocPtr docp;
        xsltStylesheetPtr sheetp;
-       int ret, file_len;
+       int ret, file_len, mode, prevSubstValue, prevExtDtdValue;
        char *file;
-       int prevSubstValue, prevExtDtdValue;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == 
FAILURE) {
                RETURN_FALSE;
        }
 
-       prevSubstValue = xmlSubstituteEntitiesDefault (1);
-       prevExtDtdValue = xmlLoadExtDtdDefaultValue;
-       xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+       mode = DOMXML_LOAD_SUBSTITUTE_ENTITIES | DOMXML_LOAD_COMPLETE_ATTRS;
+       docp = domxml_document_parser(mode, 1, file, NULL TSRMLS_CC);
 
-       sheetp = xsltParseStylesheetFile(file);
+       if (!docp)
+               RETURN_FALSE;
 
-       xmlSubstituteEntitiesDefault (prevSubstValue);
+       prevSubstValue = xmlSubstituteEntitiesDefault(1);
+       prevExtDtdValue = xmlLoadExtDtdDefaultValue;
+       xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+       sheetp = xsltParseStylesheetDoc(docp);
+       xmlSubstituteEntitiesDefault(prevSubstValue);
        xmlLoadExtDtdDefaultValue = prevExtDtdValue;
 
-       if (!sheetp)
+       if (!sheetp) {
+               xmlFreeDoc(docp);
                RETURN_FALSE;
+       }
 
        rv = php_xsltstylesheet_new(sheetp, &ret TSRMLS_CC);
        DOMXML_RET_ZVAL(rv);

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to