]> granicus.if.org Git - libexpat/commitdiff
Fix for bug # 695407: Reserved prefixes and namespace names.
authorKarl Waclawek <kwaclaw@users.sourceforge.net>
Fri, 24 Dec 2004 18:00:28 +0000 (18:00 +0000)
committerKarl Waclawek <kwaclaw@users.sourceforge.net>
Fri, 24 Dec 2004 18:00:28 +0000 (18:00 +0000)
Contributed by Peter van der Beken.

expat/lib/expat.h
expat/lib/xmlparse.c

index 98c991ed64c88f770214cc7894a328973eab9ed9..73566aec710f8efa4c5da52ca14d88ad9c36cabd 100644 (file)
@@ -91,7 +91,11 @@ enum XML_Error {
   XML_ERROR_NOT_SUSPENDED,
   XML_ERROR_ABORTED,
   XML_ERROR_FINISHED,
-  XML_ERROR_SUSPEND_PE
+  XML_ERROR_SUSPEND_PE,
+  /* Added in 2.0. */
+  XML_ERROR_RESERVED_PREFIX_XML,
+  XML_ERROR_RESERVED_PREFIX_XMLNS,
+  XML_ERROR_RESERVED_NAMESPACE_URI
 };
 
 enum XML_Content_Type {
index 163ee27f2b04f9b54af08e9c122989340c477112..9fd776e9a1cff75220e47bc4b8988c1f30593d50 100644 (file)
@@ -1877,7 +1877,10 @@ XML_ErrorString(enum XML_Error code)
     XML_L("parser not suspended"),
     XML_L("parsing aborted"),
     XML_L("parsing finished"),
-    XML_L("cannot suspend in external parameter entity")
+    XML_L("cannot suspend in external parameter entity"),
+    XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
+    XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
+    XML_L("prefix must not be bound to one of the reserved namespace names")
   };
   if (code > 0 && code < sizeof(message)/sizeof(message[0]))
     return message[code];
@@ -2931,8 +2934,64 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
   if (*uri == XML_T('\0') && prefix->name)
     return XML_ERROR_UNDECLARING_PREFIX;
 
-  for (len = 0; uri[len]; len++)
-    ;
+  if (ns) {
+    static const XML_Char xmlNamespace[] = {
+      'h', 't', 't', 'p', ':', '/', '/',
+      'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+      'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
+      'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
+    };
+    static const int xmlLen = 
+      (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
+    static const XML_Char xmlnsNamespace[] = {
+      'h', 't', 't', 'p', ':', '/', '/',
+      'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
+      '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
+    };
+    static const int xmlnsLen = 
+      (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
+
+    XML_Bool mustBeXML = XML_FALSE;
+    XML_Bool isXML = XML_TRUE;
+    XML_Bool isXMLNS = XML_TRUE;
+
+    if (prefix->name
+        && prefix->name[0] == XML_T('x')
+        && prefix->name[1] == XML_T('m')
+        && prefix->name[2] == XML_T('l')) {
+
+      /* Not allowed to bind xmlns */
+      if (prefix->name[3] == XML_T('n')
+          && prefix->name[4] == XML_T('s')
+          && prefix->name[5] == XML_T('\0'))
+        return XML_ERROR_RESERVED_PREFIX_XMLNS;
+
+      if (prefix->name[3] == XML_T('\0'))
+        mustBeXML = XML_TRUE;
+    }
+
+    for (len = 0; uri[len]; len++) {
+      if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
+        isXML = XML_FALSE;
+
+      if (!mustBeXML && isXMLNS 
+          && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
+        isXMLNS = XML_FALSE;
+    }
+    isXML = isXML && len == xmlLen;
+    isXMLNS = isXMLNS && len == xmlnsLen;
+
+    if (mustBeXML != isXML)
+      return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
+                       : XML_ERROR_RESERVED_NAMESPACE_URI;
+
+    if (isXMLNS)
+      return XML_ERROR_RESERVED_NAMESPACE_URI;
+  }
+  else
+    for (len = 0; uri[len]; len++)
+      ;
+
   if (namespaceSeparator)
     len++;
   if (freeBindingList) {