Bug 411103 - document.createElement(bad) (and the NS version) throwing wrong exception. Fixes two acid3 tests as well. r=peterv, sr=jst, a=schrep

This commit is contained in:
jwalden@mit.edu 2008-02-11 20:14:57 -08:00
Родитель cadf807803
Коммит b101d622c5
5 изменённых файлов: 192 добавлений и 29 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -64,6 +64,7 @@ _TEST_FILES = \
test_bug397571.html \
test_bug400204.html \
test_bug404748.html \
test_bug411103.html \
$(NULL)
libs:: $(_TEST_FILES)

Просмотреть файл

@ -0,0 +1,162 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=411103
-->
<head>
<title>Test for Bug 411103</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=411103">Mozilla Bug 411103</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 411103 **/
var allNSTests =
[
{ args: [undefined, undefined] },
{ args: [null, undefined] },
{ args: [undefined, null], code: 5 },
{ args: [null, null], code: 5 },
{ args: [null, ""], code: 5 },
{ args: ["", null], code: 5 },
{ args: ["", ""], code: 5 },
{ args: [null, "<div>"], code: 5 },
{ args: [null, "0div"], code: 5 },
{ args: [null, "di v"], code: 5 },
{ args: [null, "di<v"], code: 5 },
{ args: [null, "-div"], code: 5 },
{ args: [null, ".div"], code: 5 },
{ args: ["http://example.com/", "<div>"], code: 5 },
{ args: ["http://example.com/", "0div"], code: 5 },
{ args: ["http://example.com/", "di<v"], code: 5 },
{ args: ["http://example.com/", "-div"], code: 5 },
{ args: ["http://example.com/", ".div"], code: 5 },
{ args: [null, ":div"], code: 14 },
{ args: [null, "div:"], code: 14 },
{ args: ["http://example.com/", ":div"], code: 14 },
{ args: ["http://example.com/", "div:"], code: 14 },
{ args: [null, "d:iv"], code: 14 },
{ args: [null, "a:b:c"], code: 14, message: "valid XML name, invalid QName" },
{ args: ["http://example.com/", "a:b:c"], code: 14, message: "valid XML name, invalid QName" },
{ args: [null, "a::c"], code: 14, message: "valid XML name, invalid QName" },
{ args: ["http://example.com/", "a::c"], code: 14, message: "valid XML name, invalid QName" },
{ args: ["http://example.com/", "a:0"], code: 5, message: "valid XML name, not a valid QName" },
{ args: ["http://example.com/", "0:a"], code: 5, message: "0 at start makes it not a valid XML name" },
{ args: ["http://example.com/", "a:_"] },
{ args: ["http://example.com/", "a:\u0BC6"], code: 14,
message: "non-ASCII character after colon is CombiningChar, which is " +
"NCNameChar but not (Letter | \"_\") so invalid at start of " +
"NCName (but still a valid XML name, hence not 5)" },
{ args: ["http://example.com/", "\u0BC6:a"], code: 14,
message: "non-ASCII character after colon is CombiningChar, which is " +
"NCNameChar but not (Letter | \"_\") so invalid at start of " +
"NCName (Gecko chooses to throw 14 here, but either is valid " +
"as this is both an invalid XML name and an invalid QName)" },
{ args: ["http://example.com/", "a:a\u0BC6"] },
{ args: ["http://example.com/", "a\u0BC6:a"] },
{ args: ["http://example.com/", "xml:test"], code: 14, message: "binding xml prefix wrong" },
{ args: ["http://example.com/", "xmlns:test"], code: 14, message: "binding xmlns prefix wrong" },
{ args: ["http://www.w3.org/2000/xmlns/", "x:test"], code: 14, message: "binding namespace namespace to wrong prefix" },
{ args: ["http://www.w3.org/2000/xmlns/", "xmlns:test"] },
{ args: ["http://www.w3.org/XML/1998/namespace", "xml:test"] },
{ args: ["http://www.w3.org/XML/1998/namespace", "x:test"] },
];
var allNoNSTests =
[
{ args: [undefined] },
{ args: [null], code: 5 },
{ args: [""], code: 5 },
{ args: ["<div>"], code: 5 },
{ args: ["0div"], code: 5 },
{ args: ["di v"], code: 5 },
{ args: ["di<v"], code: 5 },
{ args: ["-div"], code: 5 },
{ args: [".div"], code: 5 },
{ args: [":div"], code: 5 },
{ args: ["div:"], message: "valid XML name, invalid QName" },
{ args: ["d:iv"] },
{ args: ["a:b:c"], message: "valid XML name, invalid QName" },
{ args: ["a::c"], message: "valid XML name, invalid QName" },
{ args: ["a::c:"], message: "valid XML name, invalid QName" },
{ args: ["a:0"], message: "valid XML name, not a valid QName" },
{ args: ["0:a"], code: 5, message: "0 at start makes it not a valid XML name" },
{ args: ["a:_"] },
{ args: ["a:\u0BC6"],
message: "non-ASCII character after colon is CombiningChar, which is " +
"valid in pre-namespace XML" },
{ args: ["\u0BC6:a"], code: 5, message: "not a valid start character" },
{ args: ["a:a\u0BC6"] },
{ args: ["a\u0BC6:a"] },
{ args: ["xml:test"] },
{ args: ["xmlns:test"] },
{ args: ["x:test"] },
{ args: ["xmlns:test"] },
];
function sourceify(v)
{
switch (typeof v)
{
case "undefined":
return v;
case "string":
return '"' + v.replace('"', '\\"') + '"';
default:
return String(v);
}
}
function sourceifyArgs(args)
{
var copy = new Array(args.length);
for (var i = 0, sz = args.length; i < sz; i++)
copy[i] = sourceify(args[i]);
return copy.join(", ");
}
function runTests(tests, methodName)
{
for (var i = 0, sz = tests.length; i < sz; i++)
{
var test = tests[i];
var argStr = sourceifyArgs(test.args);
try
{
document[methodName].apply(document, test.args);
var msg = "expected no exception for " +
"document." + methodName + "(" + argStr + ")";
if ("message" in test)
msg += "; " + test.message;
ok(!("code" in test), msg);
}
catch (e)
{
msg = "exception code for document." + methodName + "(" + argStr + ")";
if ("message" in test)
msg += "; " + test.message;
is(e.code, test.code || "no exception", msg);
}
}
}
runTests(allNSTests, "createElementNS");
runTests(allNoNSTests, "createElement");
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;
}