зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1321970 - escape unmatched parens in property rewriter; r=gl
MozReview-Commit-ID: 2rs07e8O0ab --HG-- extra : rebase_source : 78c24247bfed6450cb2ce487280da57039c20bc0
This commit is contained in:
Родитель
f71ff2641e
Коммит
57e5c3f0e1
|
@ -481,6 +481,50 @@ const TEST_DATA = [
|
||||||
index: 2},
|
index: 2},
|
||||||
expected: "position:absolute;top50px;height:50px;width:60px;",
|
expected: "position:absolute;top50px;height:50px;width:60px;",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
desc: "url regression test for bug 1321970",
|
||||||
|
input: "",
|
||||||
|
instruction: {type: "create", name: "p", value: "url(", priority: "",
|
||||||
|
index: 0, enabled: true},
|
||||||
|
expected: "p: url();",
|
||||||
|
changed: {0: "url()"}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
desc: "url semicolon regression test for bug 1321970",
|
||||||
|
input: "",
|
||||||
|
instruction: {type: "create", name: "p", value: "url(;", priority: "",
|
||||||
|
index: 0, enabled: true},
|
||||||
|
expected: "p: url();",
|
||||||
|
changed: {0: "url()"}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
desc: "basic regression test for bug 1321970",
|
||||||
|
input: "",
|
||||||
|
instruction: {type: "create", name: "p", value: "(", priority: "",
|
||||||
|
index: 0, enabled: true},
|
||||||
|
expected: "p: \\(;",
|
||||||
|
changed: {0: "\\("}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
desc: "unbalanced regression test for bug 1321970",
|
||||||
|
input: "",
|
||||||
|
instruction: {type: "create", name: "p", value: "({[})", priority: "",
|
||||||
|
index: 0, enabled: true},
|
||||||
|
expected: "p: ({\\[});",
|
||||||
|
changed: {0: "({\\[})"}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
desc: "function regression test for bug 1321970",
|
||||||
|
input: "",
|
||||||
|
instruction: {type: "create", name: "p", value: "func(1,2)", priority: "",
|
||||||
|
index: 0, enabled: true},
|
||||||
|
expected: "p: func(1,2);",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function rewriteDeclarations(inputString, instruction, defaultIndentation) {
|
function rewriteDeclarations(inputString, instruction, defaultIndentation) {
|
||||||
|
|
|
@ -601,12 +601,45 @@ RuleRewriter.prototype = {
|
||||||
* to be "lexically safe".
|
* to be "lexically safe".
|
||||||
*/
|
*/
|
||||||
sanitizePropertyValue: function (text) {
|
sanitizePropertyValue: function (text) {
|
||||||
|
// Start by stripping any trailing ";". This is done here to
|
||||||
|
// avoid the case where the user types "url(" (which is turned
|
||||||
|
// into "url(;" by the rule view before coming here), being turned
|
||||||
|
// into "url(;)" by this code -- due to the way "url(...)" is
|
||||||
|
// parsed as a single token.
|
||||||
|
text = text.replace(/;$/, "");
|
||||||
let lexer = getCSSLexer(text);
|
let lexer = getCSSLexer(text);
|
||||||
|
|
||||||
let result = "";
|
let result = "";
|
||||||
let previousOffset = 0;
|
let previousOffset = 0;
|
||||||
let braceDepth = 0;
|
let parenStack = [];
|
||||||
let anySanitized = false;
|
let anySanitized = false;
|
||||||
|
|
||||||
|
// Push a closing paren on the stack.
|
||||||
|
let pushParen = (token, closer) => {
|
||||||
|
result += text.substring(previousOffset, token.startOffset);
|
||||||
|
parenStack.push({closer, offset: result.length});
|
||||||
|
result += text.substring(token.startOffset, token.endOffset);
|
||||||
|
previousOffset = token.endOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pop a closing paren from the stack.
|
||||||
|
let popSomeParens = (closer) => {
|
||||||
|
while (parenStack.length > 0) {
|
||||||
|
let paren = parenStack.pop();
|
||||||
|
|
||||||
|
if (paren.closer === closer) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found a non-matching closing paren, so quote it. Note that
|
||||||
|
// these are processed in reverse order.
|
||||||
|
result = result.substring(0, paren.offset) + "\\" +
|
||||||
|
result.substring(paren.offset);
|
||||||
|
anySanitized = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
let token = lexer.nextToken();
|
let token = lexer.nextToken();
|
||||||
if (!token) {
|
if (!token) {
|
||||||
|
@ -624,14 +657,22 @@ RuleRewriter.prototype = {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "{":
|
case "{":
|
||||||
++braceDepth;
|
pushParen(token, "}");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "(":
|
||||||
|
pushParen(token, ")");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "[":
|
||||||
|
pushParen(token, "]");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "}":
|
case "}":
|
||||||
--braceDepth;
|
case ")":
|
||||||
if (braceDepth < 0) {
|
case "]":
|
||||||
// Found an unmatched close bracket.
|
// Did we find an unmatched close bracket?
|
||||||
braceDepth = 0;
|
if (!popSomeParens(token.text)) {
|
||||||
// Copy out text from |previousOffset|.
|
// Copy out text from |previousOffset|.
|
||||||
result += text.substring(previousOffset, token.startOffset);
|
result += text.substring(previousOffset, token.startOffset);
|
||||||
// Quote the offending symbol.
|
// Quote the offending symbol.
|
||||||
|
@ -641,9 +682,14 @@ RuleRewriter.prototype = {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (token.tokenType === "function") {
|
||||||
|
pushParen(token, ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix up any unmatched parens.
|
||||||
|
popSomeParens(null);
|
||||||
|
|
||||||
// Copy out any remaining text, then any needed terminators.
|
// Copy out any remaining text, then any needed terminators.
|
||||||
result += text.substring(previousOffset, text.length);
|
result += text.substring(previousOffset, text.length);
|
||||||
let eofFixup = lexer.performEOFFixup("", true);
|
let eofFixup = lexer.performEOFFixup("", true);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче