Bug 1321970 - escape unmatched parens in property rewriter; r=gl

MozReview-Commit-ID: 2rs07e8O0ab

--HG--
extra : rebase_source : 78c24247bfed6450cb2ce487280da57039c20bc0
This commit is contained in:
Tom Tromey 2017-03-16 07:46:53 +01:00
Родитель f71ff2641e
Коммит 57e5c3f0e1
2 изменённых файлов: 96 добавлений и 6 удалений

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

@ -481,6 +481,50 @@ const TEST_DATA = [
index: 2},
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) {

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

@ -601,12 +601,45 @@ RuleRewriter.prototype = {
* to be "lexically safe".
*/
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 result = "";
let previousOffset = 0;
let braceDepth = 0;
let parenStack = [];
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) {
let token = lexer.nextToken();
if (!token) {
@ -624,14 +657,22 @@ RuleRewriter.prototype = {
break;
case "{":
++braceDepth;
pushParen(token, "}");
break;
case "(":
pushParen(token, ")");
break;
case "[":
pushParen(token, "]");
break;
case "}":
--braceDepth;
if (braceDepth < 0) {
// Found an unmatched close bracket.
braceDepth = 0;
case ")":
case "]":
// Did we find an unmatched close bracket?
if (!popSomeParens(token.text)) {
// Copy out text from |previousOffset|.
result += text.substring(previousOffset, token.startOffset);
// Quote the offending symbol.
@ -641,9 +682,14 @@ RuleRewriter.prototype = {
}
break;
}
} else if (token.tokenType === "function") {
pushParen(token, ")");
}
}
// Fix up any unmatched parens.
popSomeParens(null);
// Copy out any remaining text, then any needed terminators.
result += text.substring(previousOffset, text.length);
let eofFixup = lexer.performEOFFixup("", true);