Merge branch 'tizen_base' of ssh://review.tizen.org:29418/platform/upstream/libxml2...
[platform/upstream/libxml2.git] / SAX2.c
diff --git a/SAX2.c b/SAX2.c
index 8a6d204..0f261b7 100644 (file)
--- a/SAX2.c
+++ b/SAX2.c
@@ -12,6 +12,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
+#include <stddef.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/tree.h>
 #include <libxml/parser.h>
@@ -55,7 +56,7 @@
  * @ctxt:  an XML validation parser context
  * @msg:   a string to accompany the error message
  */
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
     xmlStructuredErrorFunc schannel = NULL;
     const char *str1 = "out of memory\n";
@@ -93,7 +94,7 @@ xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
  *
  * Handle a validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
             const char *msg, const char *str1, const char *str2)
 {
@@ -133,7 +134,7 @@ xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -164,7 +165,7 @@ xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  *
  * Handle a parser warning
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                const char *msg, const xmlChar *str1)
 {
@@ -189,7 +190,7 @@ xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  *
  * Handle a namespace error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
             const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -213,7 +214,7 @@ xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  *
  * Handle a namespace warning
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
              const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -994,12 +995,12 @@ xmlSAX2StartDocument(void *ctx)
 #ifdef LIBXML_HTML_ENABLED
        if (ctxt->myDoc == NULL)
            ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
-       ctxt->myDoc->properties = XML_DOC_HTML;
-       ctxt->myDoc->parseFlags = ctxt->options;
        if (ctxt->myDoc == NULL) {
            xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
            return;
        }
+       ctxt->myDoc->properties = XML_DOC_HTML;
+       ctxt->myDoc->parseFlags = ctxt->options;
 #else
         xmlGenericError(xmlGenericErrorContext,
                "libxml2 built without HTML support\n");
@@ -1078,7 +1079,7 @@ xmlSAX2EndDocument(void *ctx)
     }
 }
 
-#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 /**
  * xmlSAX2AttributeInternal:
  * @ctx: the user data (XML parser context)
@@ -1177,6 +1178,14 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
            val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
                                          0,0,0);
            ctxt->depth--;
+           if (val == NULL) {
+               xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+               if (name != NULL)
+                   xmlFree(name);
+                if (nval != NULL)
+                    xmlFree(nval);
+               return;
+           }
        } else {
            val = (xmlChar *) value;
        }
@@ -1236,6 +1245,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
                xmlFree(ns);
                if (name != NULL)
                    xmlFree(name);
+                if (nval != NULL)
+                    xmlFree(nval);
                return;
            }
        } else {
@@ -1305,6 +1316,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
                                              name, namespace->href);
                         ctxt->wellFormed = 0;
                         if (ctxt->recovery == 0) ctxt->disableSAX = 1;
+                        if (name != NULL)
+                            xmlFree(name);
                         goto error;
                     }
                 }
@@ -1822,7 +1835,7 @@ xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
 #endif
     nodePop(ctxt);
 }
-#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
+#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
 
 /*
  * xmlSAX2TextNode:
@@ -1902,7 +1915,7 @@ skip:
            else {
                ret->line = 65535;
                if (ctxt->options & XML_PARSE_BIG_LINES)
-                   ret->psvi = (void *) (long) ctxt->input->line;
+                   ret->psvi = (void *) (ptrdiff_t) ctxt->input->line;
            }
        }
     }
@@ -2145,6 +2158,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
             */
            if (dup == NULL)
                dup = xmlStrndup(value, valueend - value);
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 #ifdef LIBXML_VALID_ENABLED
            if (xmlValidateNCName(dup, 1) != 0) {
                xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
@@ -2152,6 +2166,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
                            (const char *) dup, NULL);
            }
 #endif
+#endif
            xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
        } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
            /* might be worth duplicate entry points and not copy */
@@ -2201,6 +2216,7 @@ xmlSAX2StartElementNs(void *ctx,
     xmlNodePtr parent;
     xmlNsPtr last = NULL, ns;
     const xmlChar *uri, *pref;
+    xmlChar *lname = NULL;
     int i, j;
 
     if (ctx == NULL) return;
@@ -2220,6 +2236,20 @@ xmlSAX2StartElementNs(void *ctx,
     }
 
     /*
+     * Take care of the rare case of an undefined namespace prefix
+     */
+    if ((prefix != NULL) && (URI == NULL)) {
+        if (ctxt->dictNames) {
+           const xmlChar *fullname;
+
+           fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
+           if (fullname != NULL)
+               localname = fullname;
+       } else {
+           lname = xmlBuildQName(localname, prefix, NULL, 0);
+       }
+    }
+    /*
      * allocate the node
      */
     if (ctxt->freeElems != NULL) {
@@ -2232,7 +2262,10 @@ xmlSAX2StartElementNs(void *ctx,
        if (ctxt->dictNames)
            ret->name = localname;
        else {
-           ret->name = xmlStrdup(localname);
+           if (lname == NULL)
+               ret->name = xmlStrdup(localname);
+           else
+               ret->name = lname;
            if (ret->name == NULL) {
                xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
                return;
@@ -2244,8 +2277,11 @@ xmlSAX2StartElementNs(void *ctx,
        if (ctxt->dictNames)
            ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
                                       (xmlChar *) localname, NULL);
-       else
+       else if (lname == NULL)
            ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
+       else
+           ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
+                                      (xmlChar *) lname, NULL);
        if (ret == NULL) {
            xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
            return;
@@ -2282,7 +2318,7 @@ xmlSAX2StartElementNs(void *ctx,
        } else {
             /*
              * any out of memory error would already have been raised
-             * but we can't be garanteed it's the actual error due to the
+             * but we can't be guaranteed it's the actual error due to the
              * API, best is to skip in this case
              */
            continue;
@@ -2352,8 +2388,33 @@ xmlSAX2StartElementNs(void *ctx,
      */
     if (nb_attributes > 0) {
         for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
+           /*
+            * Handle the rare case of an undefined atribute prefix
+            */
+           if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
+               if (ctxt->dictNames) {
+                   const xmlChar *fullname;
+
+                   fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
+                                             attributes[j]);
+                   if (fullname != NULL) {
+                       xmlSAX2AttributeNs(ctxt, fullname, NULL,
+                                          attributes[j+3], attributes[j+4]);
+                       continue;
+                   }
+               } else {
+                   lname = xmlBuildQName(attributes[j], attributes[j+1],
+                                         NULL, 0);
+                   if (lname != NULL) {
+                       xmlSAX2AttributeNs(ctxt, lname, NULL,
+                                          attributes[j+3], attributes[j+4]);
+                       xmlFree(lname);
+                       continue;
+                   }
+               }
+           }
            xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
-                              attributes[j+3], attributes[j+4]);
+                              attributes[j+3], attributes[j+4]);
        }
     }
 
@@ -2524,6 +2585,10 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
                       (xmlDictOwns(ctxt->dict, lastChild->content))) {
                lastChild->content = xmlStrdup(lastChild->content);
            }
+           if (lastChild->content == NULL) {
+               xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL");
+               return;
+           }
             if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) &&
                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
@@ -2747,7 +2812,8 @@ xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
        xmlTextConcat(lastChild, value, len);
     } else {
        ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
-       xmlAddChild(ctxt->node, ret);
+       if (xmlAddChild(ctxt->node, ret) == NULL)
+               xmlFreeNode(ret);
     }
 }