Bug 1230172. Update CSS.escape to never throw and instead replace U+0000 with U+FFFD, per recent spec change. r=dbaron

This commit is contained in:
Boris Zbarsky 2016-01-05 15:05:23 -05:00
parent 99af1f8707
commit f1705741f0
6 changed files with 22 additions and 25 deletions

View File

@ -20,6 +20,5 @@ interface CSS {
// http://dev.w3.org/csswg/cssom/#the-css.escape%28%29-method
partial interface CSS {
[Throws]
static DOMString escape(DOMString ident);
};

View File

@ -85,14 +85,9 @@ CSS::Supports(const GlobalObject& aGlobal,
/* static */ void
CSS::Escape(const GlobalObject& aGlobal,
const nsAString& aIdent,
nsAString& aReturn,
ErrorResult& aRv)
nsAString& aReturn)
{
bool success = nsStyleUtil::AppendEscapedCSSIdent(aIdent, aReturn);
if (!success) {
aRv.Throw(NS_ERROR_DOM_INVALID_CHARACTER_ERR);
}
nsStyleUtil::AppendEscapedCSSIdent(aIdent, aReturn);
}
} // namespace dom

View File

@ -35,8 +35,7 @@ public:
static void Escape(const GlobalObject& aGlobal,
const nsAString& aIdent,
nsAString& aReturn,
ErrorResult& aRv);
nsAString& aReturn);
};
} // namespace dom

View File

@ -79,7 +79,7 @@ void nsStyleUtil::AppendEscapedCSSString(const nsAString& aString,
aReturn.Append(quoteChar);
}
/* static */ bool
/* static */ void
nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn)
{
// The relevant parts of the CSS grammar are:
@ -98,7 +98,7 @@ nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn)
const char16_t* const end = aIdent.EndReading();
if (in == end)
return true;
return;
// A leading dash does not need to be escaped as long as it is not the
// *only* character in the identifier.
@ -106,7 +106,7 @@ nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn)
if (in + 1 == end) {
aReturn.Append(char16_t('\\'));
aReturn.Append(char16_t('-'));
return true;
return;
}
aReturn.Append(char16_t('-'));
@ -124,9 +124,8 @@ nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn)
for (; in != end; ++in) {
char16_t ch = *in;
if (ch == 0x00) {
return false;
}
if (ch < 0x20 || (0x7F <= ch && ch < 0xA0)) {
aReturn.Append(char16_t(0xFFFD));
} else if (ch < 0x20 || (0x7F <= ch && ch < 0xA0)) {
// Escape U+0000 through U+001F and U+007F through U+009F numerically.
aReturn.AppendPrintf("\\%hx ", *in);
} else {
@ -142,7 +141,6 @@ nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn)
aReturn.Append(ch);
}
}
return true;
}
// unquoted family names must be a sequence of idents

View File

@ -39,10 +39,9 @@ public:
// Append the identifier given by |aIdent| to |aResult|, with
// appropriate escaping so that it can be reparsed to the same
// identifier.
// Returns false if |aIdent| contains U+0000
// Returns true for all other cases
static bool AppendEscapedCSSIdent(const nsAString& aIdent,
// identifier. An exception is if aIdent contains U+0000, which
// will be escaped as U+FFFD and then reparsed back to U+FFFD.
static void AppendEscapedCSSIdent(const nsAString& aIdent,
nsAString& aResult);
static void

View File

@ -21,11 +21,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=955860
// Tests taken from:
// https://github.com/mathiasbynens/CSS.escape/blob/master/tests/tests.js
SimpleTest.doesThrow(() => CSS.escape('\0'), "InvalidCharacterError Character :\\0");
SimpleTest.doesThrow(() => CSS.escape('a\0'), "InvalidCharacterError Character : a\\0");
SimpleTest.doesThrow(() => CSS.escape('\0b'), "InvalidCharacterError Character : \\0b");
SimpleTest.doesThrow(() => CSS.escape('a\0b'), "InvalidCharacterError Character : a\\0b");
SimpleTest.doesThrow(() => CSS.escape(), 'undefined');
is(CSS.escape('\0'), '\uFFFD', "escaping for 0 char (1)");
is(CSS.escape('a\0'), 'a\uFFFD', "escaping for 0 char (2)");
is(CSS.escape('\0b'), '\uFFFDb', "escaping for 0 char (3)");
is(CSS.escape('a\0b'), 'a\uFFFDb', "escaping for 0 char (4)");
is(CSS.escape('\uFFFD'), '\uFFFD', "escaping for replacement char (1)");
is(CSS.escape('a\uFFFD'), 'a\uFFFD', "escaping replacement char (2)");
is(CSS.escape('\uFFFDb'), '\uFFFDb', "escaping replacement char (3)");
is(CSS.escape('a\uFFFDb'), 'a\uFFFDb', "escaping replacement char (4)");
is(CSS.escape(true), 'true', "escapingFailed Character : true(bool)");
is(CSS.escape(false), 'false', "escapingFailed Character : false(bool)");
is(CSS.escape(null), 'null', "escapingFailed Character : null");