From b101d622c573801b08e1b43fad63db3a37bff794 Mon Sep 17 00:00:00 2001 From: "jwalden@mit.edu" Date: Mon, 11 Feb 2008 20:14:57 -0800 Subject: [PATCH] Bug 411103 - document.createElement(bad) (and the NS version) throwing wrong exception. Fixes two acid3 tests as well. r=peterv, sr=jst, a=schrep --- content/base/src/nsDocument.cpp | 9 +- dom/tests/mochitest/bugs/Makefile.in | 1 + dom/tests/mochitest/bugs/test_bug411103.html | 162 +++++++++++++++++++ parser/expat/lib/moz_extensions.c | 47 +++--- parser/htmlparser/src/nsParserService.cpp | 2 +- 5 files changed, 192 insertions(+), 29 deletions(-) create mode 100644 dom/tests/mochitest/bugs/test_bug411103.html diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 6b9873ee51b5..333fe5ef46d9 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -5202,9 +5202,12 @@ nsDocument::CreateElem(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID, aName->GetUTF8String(&name); AppendUTF8toUTF16(name, qName); - rv = nsContentUtils::CheckQName(qName, PR_TRUE); - NS_ASSERTION(NS_SUCCEEDED(rv), - "Don't pass invalid names to nsDocument::CreateElem, " + // Note: "a:b:c" is a valid name in non-namespaces XML, and + // nsDocument::CreateElement can call us with such a name and no prefix, + // which would cause an error if we just used PR_TRUE here. + PRBool nsAware = aPrefix != nsnull || aNamespaceID != GetDefaultNamespaceID(); + NS_ASSERTION(NS_SUCCEEDED(nsContentUtils::CheckQName(qName, nsAware)), + "Don't pass invalid prefixes to nsDocument::CreateElem, " "check caller."); #endif diff --git a/dom/tests/mochitest/bugs/Makefile.in b/dom/tests/mochitest/bugs/Makefile.in index de8e64c22c2e..e23b3961bae1 100644 --- a/dom/tests/mochitest/bugs/Makefile.in +++ b/dom/tests/mochitest/bugs/Makefile.in @@ -64,6 +64,7 @@ _TEST_FILES = \ test_bug397571.html \ test_bug400204.html \ test_bug404748.html \ + test_bug411103.html \ $(NULL) libs:: $(_TEST_FILES) diff --git a/dom/tests/mochitest/bugs/test_bug411103.html b/dom/tests/mochitest/bugs/test_bug411103.html new file mode 100644 index 000000000000..45b05667299d --- /dev/null +++ b/dom/tests/mochitest/bugs/test_bug411103.html @@ -0,0 +1,162 @@ + + + + + Test for Bug 411103 + + + + + +Mozilla Bug 411103 +

+ +
+
+
+ + + diff --git a/parser/expat/lib/moz_extensions.c b/parser/expat/lib/moz_extensions.c index 1d311c84821e..1fc5afd3b4ac 100644 --- a/parser/expat/lib/moz_extensions.c +++ b/parser/expat/lib/moz_extensions.c @@ -70,32 +70,31 @@ int MOZ_XMLCheckQName(const char* ptr, const char* end, int ns_aware, do { switch (BYTE_TYPE(ptr)) { case BT_COLON: - if (ns_aware) { - if (*colon != 0 || nmstrt || ptr + 2 == end) { - /* We already encountered a colon or this is the first or the last - character so the QName is malformed. */ - result |= MOZ_EXPAT_MALFORMED; - } - *colon = ptr; - nmstrt = 1; + if (nmstrt) { + /* We're at the first character and it's a colon; it's a malformed + QName if we're namespace-aware and an invalid character otherwise. */ + return ns_aware ? MOZ_EXPAT_MALFORMED : MOZ_EXPAT_INVALID_CHARACTER; } - else if (nmstrt) { - /* This is the first character so the QName is malformed. */ - result |= MOZ_EXPAT_MALFORMED; - nmstrt = 0; + if (ns_aware && (ptr + 2 == end || *colon)) { + /* This is the last character or a second colon when we're + namespace-aware, so the QName is malformed. */ + return MOZ_EXPAT_MALFORMED; } + *colon = ptr; + nmstrt = ns_aware; /* e.g. "a:0" should be valid if !ns_aware */ break; case BT_NONASCII: - if (nmstrt) { - if (!IS_NMSTRT_CHAR_MINBPC(ptr)) { - /* If this is a valid name character the QName is malformed, - otherwise it contains an invalid character. */ - result |= IS_NAME_CHAR_MINBPC(ptr) ? MOZ_EXPAT_MALFORMED : - MOZ_EXPAT_INVALID_CHARACTER; - } + if (nmstrt && !IS_NMSTRT_CHAR_MINBPC(ptr)) { + /* If this is a valid name character and we're namespace-aware, the + QName is malformed. Otherwise, this character's invalid at the + start of a name (or, if we're namespace-aware, at the start of a + localpart). */ + return (IS_NAME_CHAR_MINBPC(ptr) && ns_aware) ? + MOZ_EXPAT_MALFORMED : + MOZ_EXPAT_INVALID_CHARACTER; } - else if (!IS_NAME_CHAR_MINBPC(ptr)) { - result |= MOZ_EXPAT_INVALID_CHARACTER; + if (!IS_NAME_CHAR_MINBPC(ptr)) { + return MOZ_EXPAT_INVALID_CHARACTER; } nmstrt = 0; break; @@ -107,13 +106,11 @@ int MOZ_XMLCheckQName(const char* ptr, const char* end, int ns_aware, case BT_NAME: case BT_MINUS: if (nmstrt) { - result |= MOZ_EXPAT_MALFORMED; - nmstrt = 0; + return MOZ_EXPAT_INVALID_CHARACTER; } break; default: - result |= MOZ_EXPAT_INVALID_CHARACTER; - nmstrt = 0; + return MOZ_EXPAT_INVALID_CHARACTER; } ptr += 2; } while (ptr != end); diff --git a/parser/htmlparser/src/nsParserService.cpp b/parser/htmlparser/src/nsParserService.cpp index ea78fb6bd886..7165704dfd28 100644 --- a/parser/htmlparser/src/nsParserService.cpp +++ b/parser/htmlparser/src/nsParserService.cpp @@ -214,7 +214,7 @@ nsParserService::CheckQName(const nsAString& aQName, } // MOZ_EXPAT_EMPTY_QNAME || MOZ_EXPAT_INVALID_CHARACTER - if (result & (1 << 0) || result & (1 << 1)) { + if (result == (1 << 0) || result == (1 << 1)) { return NS_ERROR_DOM_INVALID_CHARACTER_ERR; }