mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge backout, a=bustage fix
This commit is contained in:
commit
c10fe6c238
@ -874,7 +874,7 @@ nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request,
|
||||
window->window = widget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
|
||||
}
|
||||
#endif
|
||||
mOwner->SetWindow();
|
||||
owner->SetWindow();
|
||||
}
|
||||
|
||||
mSeekable = PR_FALSE;
|
||||
|
@ -971,7 +971,11 @@ nsCSSScanner::NextURL(nsCSSToken& aToken)
|
||||
ch = Read();
|
||||
if (ch < 0) break;
|
||||
if (ch == CSS_ESCAPE) {
|
||||
ParseAndAppendEscape(ident);
|
||||
if (!ParseAndAppendEscape(ident, PR_FALSE)) {
|
||||
ok = PR_FALSE;
|
||||
Pushback(ch);
|
||||
break;
|
||||
}
|
||||
} else if (IsWhitespace(ch)) {
|
||||
// Whitespace is allowed at the end of the URL
|
||||
EatWhiteSpace();
|
||||
@ -1002,17 +1006,21 @@ nsCSSScanner::NextURL(nsCSSToken& aToken)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsCSSScanner::ParseAndAppendEscape(nsString& aOutput)
|
||||
/**
|
||||
* Returns whether an escape was succesfully parsed; if it was not,
|
||||
* the backslash needs to be its own symbol token.
|
||||
*/
|
||||
PRBool
|
||||
nsCSSScanner::ParseAndAppendEscape(nsString& aOutput, PRBool aInString)
|
||||
{
|
||||
PRInt32 ch = Peek();
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) {
|
||||
aOutput.Append(CSS_ESCAPE);
|
||||
return;
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (IsHexDigit(ch)) {
|
||||
PRInt32 rv = 0;
|
||||
int i;
|
||||
Pushback(ch);
|
||||
for (i = 0; i < 6; i++) { // up to six digits
|
||||
ch = Read();
|
||||
if (ch < 0) {
|
||||
@ -1054,15 +1062,26 @@ nsCSSScanner::ParseAndAppendEscape(nsString& aOutput)
|
||||
if (IsWhitespace(ch))
|
||||
Pushback(ch);
|
||||
}
|
||||
return;
|
||||
return PR_TRUE;
|
||||
}
|
||||
// "Any character except a hexidecimal digit can be escaped to
|
||||
// remove its special meaning by putting a backslash in front"
|
||||
// -- CSS1 spec section 7.1
|
||||
ch = Read(); // Consume the escaped character
|
||||
if ((ch > 0) && (ch != '\n')) {
|
||||
if (ch == '\n') {
|
||||
if (!aInString) {
|
||||
// Outside of strings (which includes url() that contains a
|
||||
// string), escaped newlines aren't special, and just tokenize as
|
||||
// eCSSToken_Symbol (DELIM).
|
||||
Pushback(ch);
|
||||
return PR_FALSE;
|
||||
}
|
||||
// In strings (and in url() containing a string), escaped newlines
|
||||
// are just dropped to allow splitting over multiple lines.
|
||||
} else {
|
||||
aOutput.Append(ch);
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1071,12 +1090,18 @@ nsCSSScanner::ParseAndAppendEscape(nsString& aOutput)
|
||||
* will be aIdent with all of the identifier characters appended
|
||||
* until the first non-identifier character is seen. The termination
|
||||
* character is unread for the future re-reading.
|
||||
*
|
||||
* Returns failure when the character sequence does not form an ident at
|
||||
* all, in which case the caller is responsible for pushing back or
|
||||
* otherwise handling aChar. (This occurs only when aChar is '\'.)
|
||||
*/
|
||||
PRBool
|
||||
nsCSSScanner::GatherIdent(PRInt32 aChar, nsString& aIdent)
|
||||
{
|
||||
if (aChar == CSS_ESCAPE) {
|
||||
ParseAndAppendEscape(aIdent);
|
||||
if (!ParseAndAppendEscape(aIdent, PR_FALSE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
else if (0 < aChar) {
|
||||
aIdent.Append(aChar);
|
||||
@ -1103,7 +1128,10 @@ nsCSSScanner::GatherIdent(PRInt32 aChar, nsString& aIdent)
|
||||
aChar = Read();
|
||||
if (aChar < 0) break;
|
||||
if (aChar == CSS_ESCAPE) {
|
||||
ParseAndAppendEscape(aIdent);
|
||||
if (!ParseAndAppendEscape(aIdent, PR_FALSE)) {
|
||||
Pushback(aChar);
|
||||
break;
|
||||
}
|
||||
} else if (IsIdent(aChar)) {
|
||||
aIdent.Append(PRUnichar(aChar));
|
||||
} else {
|
||||
@ -1117,19 +1145,24 @@ nsCSSScanner::GatherIdent(PRInt32 aChar, nsString& aIdent)
|
||||
PRBool
|
||||
nsCSSScanner::ParseRef(PRInt32 aChar, nsCSSToken& aToken)
|
||||
{
|
||||
aToken.mIdent.SetLength(0);
|
||||
aToken.mType = eCSSToken_Ref;
|
||||
// Fall back for when we don't have name characters following:
|
||||
aToken.mType = eCSSToken_Symbol;
|
||||
aToken.mSymbol = aChar;
|
||||
|
||||
PRInt32 ch = Read();
|
||||
if (ch < 0) {
|
||||
return PR_FALSE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (IsIdent(ch) || ch == CSS_ESCAPE) {
|
||||
// First char after the '#' is a valid ident char (or an escape),
|
||||
// so it makes sense to keep going
|
||||
if (StartsIdent(ch, Peek())) {
|
||||
aToken.mType = eCSSToken_ID;
|
||||
nsCSSTokenType type =
|
||||
StartsIdent(ch, Peek()) ? eCSSToken_ID : eCSSToken_Ref;
|
||||
aToken.mIdent.SetLength(0);
|
||||
if (GatherIdent(ch, aToken.mIdent)) {
|
||||
aToken.mType = type;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return GatherIdent(ch, aToken.mIdent);
|
||||
}
|
||||
|
||||
// No ident chars after the '#'. Just unread |ch| and get out of here.
|
||||
@ -1143,7 +1176,9 @@ nsCSSScanner::ParseIdent(PRInt32 aChar, nsCSSToken& aToken)
|
||||
nsString& ident = aToken.mIdent;
|
||||
ident.SetLength(0);
|
||||
if (!GatherIdent(aChar, ident)) {
|
||||
return PR_FALSE;
|
||||
aToken.mType = eCSSToken_Symbol;
|
||||
aToken.mSymbol = aChar;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsCSSTokenType tokenType = eCSSToken_Ident;
|
||||
@ -1167,7 +1202,11 @@ nsCSSScanner::ParseAtKeyword(PRInt32 aChar, nsCSSToken& aToken)
|
||||
{
|
||||
aToken.mIdent.SetLength(0);
|
||||
aToken.mType = eCSSToken_AtKeyword;
|
||||
return GatherIdent(0, aToken.mIdent);
|
||||
if (!GatherIdent(0, aToken.mIdent)) {
|
||||
aToken.mType = eCSSToken_Symbol;
|
||||
aToken.mSymbol = PRUnichar('@');
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -1287,10 +1326,9 @@ nsCSSScanner::ParseNumber(PRInt32 c, nsCSSToken& aToken)
|
||||
// Look at character that terminated the number
|
||||
if (c >= 0) {
|
||||
if (StartsIdent(c, Peek())) {
|
||||
if (!GatherIdent(c, ident)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (GatherIdent(c, ident)) {
|
||||
type = eCSSToken_Dimension;
|
||||
}
|
||||
} else if ('%' == c) {
|
||||
type = eCSSToken_Percentage;
|
||||
value = value / 100.0f;
|
||||
@ -1367,7 +1405,21 @@ nsCSSScanner::ParseString(PRInt32 aStop, nsCSSToken& aToken)
|
||||
break;
|
||||
}
|
||||
if (ch == CSS_ESCAPE) {
|
||||
ParseAndAppendEscape(aToken.mIdent);
|
||||
if (!ParseAndAppendEscape(aToken.mIdent, PR_TRUE)) {
|
||||
aToken.mType = eCSSToken_Bad_String;
|
||||
Pushback(ch);
|
||||
#ifdef CSS_REPORT_PARSE_ERRORS
|
||||
// For strings, the only case where ParseAndAppendEscape will
|
||||
// return false is when there's a backslash to start an escape
|
||||
// immediately followed by end-of-stream. In that case, the
|
||||
// correct tokenization is badstring *followed* by a DELIM for
|
||||
// the backslash, but as far as the author is concerned, it
|
||||
// works pretty much the same as an unterminated string, so we
|
||||
// use the same error message.
|
||||
ReportUnexpectedToken(aToken, "SEUnterminatedString");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
aToken.mIdent.Append(ch);
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ protected:
|
||||
PRBool LookAheadOrEOF(PRUnichar aChar); // expect either aChar or EOF
|
||||
void EatWhiteSpace();
|
||||
|
||||
void ParseAndAppendEscape(nsString& aOutput);
|
||||
PRBool ParseAndAppendEscape(nsString& aOutput, PRBool aInString);
|
||||
PRBool ParseIdent(PRInt32 aChar, nsCSSToken& aResult);
|
||||
PRBool ParseAtKeyword(PRInt32 aChar, nsCSSToken& aResult);
|
||||
PRBool ParseNumber(PRInt32 aChar, nsCSSToken& aResult);
|
||||
|
@ -48,7 +48,7 @@ base + "#a {color: rgb\n(255, 0, 0)}",
|
||||
"@threedee maroon url('asdf\n) ra('asdf\n); " + base,
|
||||
"@threedee {maroon url('asdf\n) ra('asdf\n);} " + base,
|
||||
"div[title='zxcv weeqweqeweasd\\D\\A a']{color:green}",
|
||||
"div[title~='weeqweqeweasd\\D\\A a']{color:green}",
|
||||
"div[title~='weeqweqeweasd']{color:green}",
|
||||
base + "#a\\\n{color:red}",
|
||||
base + "#a\v{color:red}",
|
||||
|
||||
@ -129,11 +129,7 @@ base + "#a {color: rgb(255.0, 0, 0)}",
|
||||
"#a {color: rgb(0, 128, 0)}",
|
||||
"#a {color: rgb(0%, 50%, 0%)}",
|
||||
"#a {color: rgb(0%, 49.999999999999%, 0%)}",
|
||||
], prop: "color", pseudo: "",
|
||||
todo: {
|
||||
"div[title~='weeqweqeweasd\\D\\A a']{color:green}" : 1,
|
||||
"div {color:green}#a\\\n{color:red}" : 1
|
||||
}
|
||||
], prop: "color", pseudo: ""
|
||||
},
|
||||
|
||||
// Border tests
|
||||
|
@ -180,6 +180,13 @@ div.setAttribute("style", "color: url(/*); color: green");
|
||||
is(div.style.color, 'green',
|
||||
"URL tokenized correctly outside properties taking URLs");
|
||||
|
||||
div.style.listStyleImage = 'url("foo\\\nbar1")';
|
||||
is(div.style.listStyleImage, 'url("foobar1")',
|
||||
"escaped newline allowed in string form of URL");
|
||||
div.style.listStyleImage = 'url(foo\\\nbar2)';
|
||||
is(div.style.listStyleImage, 'url("foobar1")',
|
||||
"escaped newline NOT allowed in NON-string form of URL");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -233,6 +233,18 @@ function run() {
|
||||
});
|
||||
}
|
||||
|
||||
function test_unparseable_via_api(selector)
|
||||
{
|
||||
try {
|
||||
// Test that it is also unparseable when followed by EOF.
|
||||
ifdoc.body.mozMatchesSelector(selector);
|
||||
ok(false, "selector '" + selector + "' plus EOF is parse error");
|
||||
} catch(ex) {
|
||||
is(ex.code, DOMException.SYNTAX_ERR,
|
||||
"selector '" + selector + "' plus EOF is parse error");
|
||||
}
|
||||
}
|
||||
|
||||
function test_balanced_unparseable(selector)
|
||||
{
|
||||
var zi1 = ++gCounter;
|
||||
@ -248,6 +260,7 @@ function run() {
|
||||
"selector " + selector + " error was recovered from");
|
||||
ifdoc.body.innerHTML = "";
|
||||
style_text.data = "";
|
||||
test_unparseable_via_api(selector);
|
||||
}
|
||||
|
||||
function test_unbalanced_unparseable(selector)
|
||||
@ -263,6 +276,7 @@ function run() {
|
||||
"sheet should have no rules since " + selector + " is parse error");
|
||||
ifdoc.body.innerHTML = "";
|
||||
style_text.data = "";
|
||||
test_unparseable_via_api(selector);
|
||||
}
|
||||
|
||||
|
||||
@ -891,6 +905,26 @@ function run() {
|
||||
bodychildset([2, 3, 8]),
|
||||
bodychildset([0, 1, 4, 5, 6, 7]));
|
||||
|
||||
// Test that we don't tokenize an empty HASH.
|
||||
test_balanced_unparseable("#");
|
||||
test_balanced_unparseable("# ");
|
||||
test_balanced_unparseable("#, p");
|
||||
test_balanced_unparseable("# , p");
|
||||
test_balanced_unparseable("p #");
|
||||
test_balanced_unparseable("p # ");
|
||||
test_balanced_unparseable("p #, p");
|
||||
test_balanced_unparseable("p # , p");
|
||||
|
||||
// Test that a backslash alone is not treated as an escape.
|
||||
test_unparseable_via_api("#\\");
|
||||
|
||||
// Test that newline escapes are only supported in strings.
|
||||
test_balanced_unparseable("di\\\nv");
|
||||
test_balanced_unparseable("div \\\n p");
|
||||
test_balanced_unparseable("div\\\n p");
|
||||
test_balanced_unparseable("div \\\np");
|
||||
test_balanced_unparseable("div\\\np");
|
||||
|
||||
run_deferred_tests();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user