Add license file
[platform/upstream/libxml2.git] / SAX2.c
diff --git a/SAX2.c b/SAX2.c
index 8a6d204..5cbb700 100644 (file)
--- a/SAX2.c
+++ b/SAX2.c
@@ -55,7 +55,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 +93,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 +133,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 +164,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 +189,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 +213,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 +994,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 +1078,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 +1177,12 @@ 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);
+               return;
+           }
        } else {
            val = (xmlChar *) value;
        }
@@ -1822,7 +1828,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:
@@ -2145,6 +2151,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 +2159,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 +2209,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 +2229,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 +2255,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 +2270,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;
@@ -2352,8 +2381,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 +2578,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");