From 8628551c5af47cde5b9addbcd2498602f57ad882 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Tue, 12 Oct 2010 17:34:39 -0400 Subject: [PATCH] Fix parsing of invalid JSON strings in arguments, and serialization of strings containing tabs and newlines. Closes issue #72. --- common/content/commands.js | 8 ++++++-- common/content/javascript.js | 6 ++++-- common/content/options.js | 9 +++++---- common/content/tabs.js | 2 +- common/locale/en-US/cmdline.xml | 6 ++---- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/common/content/commands.js b/common/content/commands.js index 0aae3402..7fac084c 100644 --- a/common/content/commands.js +++ b/common/content/commands.js @@ -975,6 +975,8 @@ const Commands = Module("commands", { let quote = null; let len = str.length; + function fixEscapes(str) str.replace(/\\(?:["\\\/bfnrt]|u[a-fA-F]{4}|(.))/g, function (m, n1) n1 || m); + // Fix me. if (isString(sep)) sep = RegExp(sep); @@ -987,7 +989,7 @@ const Commands = Module("commands", { if ((res = re2.exec(str))) arg += keepQuotes ? res[0] : res[2].replace(/\\(.)/g, "$1"); else if ((res = /^(")((?:[^\\"]|\\.)*)("?)/.exec(str))) - arg += keepQuotes ? res[0] : JSON.parse(res[0] + (res[3] ? "" : '"')); + arg += keepQuotes ? res[0] : JSON.parse(fixEscapes(res[0]) + (res[3] ? "" : '"')); else if ((res = /^(')((?:[^']|'')*)('?)/.exec(str))) arg += keepQuotes ? res[0] : res[2].replace("''", "'", "g"); else @@ -1003,7 +1005,9 @@ const Commands = Module("commands", { return [len - str.length, arg, quote]; }, - quote: function quote(str) Commands.quoteArg[/[\s"'\\]|^$/.test(str) ? "'" : ""](str) + quote: function quote(str) Commands.quoteArg[/[\s"'\\]|^$/.test(str) + ? (/[\b\f\n\r\t]/.test(str) ? '"' : "'") + : ""](str) }, { completion: function () { completion.command = function command(context) { diff --git a/common/content/javascript.js b/common/content/javascript.js index a29ffadf..3698e4ce 100644 --- a/common/content/javascript.js +++ b/common/content/javascript.js @@ -19,6 +19,8 @@ const JavaScript = Module("javascript", { this._lastIdx = 0; this._cacheKey = null; + + this._nullSandbox = Cu.Sandbox("about:blank"); }, get completers() JavaScript.completers, // For backward compatibility @@ -478,8 +480,8 @@ const JavaScript = Module("javascript", { // The top of the stack is the sting we're completing. // Wrap it in its delimiters and eval it to process escape sequences. - let string = this._str.substring(this._get(-1).offset + 1, this._lastIdx); - string = JSON.parse(this._last + string + this._last); + let string = this._str.substring(this._get(-1).offset + 1, this._lastIdx).replace(/((?:\\\\)*)\\/, "$1"); + string = Cu.evalInSandbox(this._last + string + this._last, this._nullSandbox); // Is this an object accessor? if (this._get(-2).char == "[") { // Are we inside of []? diff --git a/common/content/options.js b/common/content/options.js index 7f05e8fe..91619779 100644 --- a/common/content/options.js +++ b/common/content/options.js @@ -377,9 +377,7 @@ const Option = Class("Option", { SCOPE_BOTH: 3, has: { - toggleAll: function toggleAll() toggleAll.supercall(this, "all") - ? Array.some(arguments, function (val) this.value.indexOf(val) === -1, this) - : toggleAll.superapply(this, arguments), + toggleAll: function toggleAll() toggleAll.supercall(this, "all") ^ !!toggleAll.superapply(this, arguments), }, parseRegex: function (value, result, flags) { @@ -473,7 +471,10 @@ const Option = Class("Option", { } return res; }, - quote: function quote(str, re) Commands.quoteArg[/[\s|"'\\,]|^$/.test(str) || re && re.test && re.test(str) ? "'" : ""](str, re), + quote: function quote(str, re) + Commands.quoteArg[/[\s|"'\\,]|^$/.test(str) || re && re.test && re.test(str) + ? (/[\b\f\n\r\t]/.test(str) ? '"' : "'") + : ""](str, re), ops: { boolean: function (operator, values, scope, invert) { diff --git a/common/content/tabs.js b/common/content/tabs.js index f9f47380..64cfbac5 100644 --- a/common/content/tabs.js +++ b/common/content/tabs.js @@ -1034,7 +1034,7 @@ const Tabs = Module("tabs", { for (let group in values(activateGroups)) if (group[2]) options.safeSetPref("browser.tabs." + group[2], - !(valueSet["all"] || valueSet[group[0]]), + !(valueSet["all"] ^ valueSet[group[0]]), "See the 'activate' option"); return newValues; } diff --git a/common/locale/en-US/cmdline.xml b/common/locale/en-US/cmdline.xml index 019fd28f..099368d8 100644 --- a/common/locale/en-US/cmdline.xml +++ b/common/locale/en-US/cmdline.xml @@ -259,13 +259,11 @@ Any character inside of double quotes except for " and \ is interpreted literally. A literal double quote may be included by preceding it with a backslash. Any other occurrence of a - backslash starts an escape sequence as in JavaScript strings. Among - the available escape sequences are: + backslash starts an escape sequence as in JSON strings. + Among the available escape sequences are:
\n
A newline character.
\t
A tab character.
-
\0nn
Where each n is a digit between 0 and 7, represents an octal character code.
-
\xdd
Where each d is a digit between 0 and F, represents a hexidecimal character code.
\uxxxx
Where each x is a digit between 0 and F, a Unicode character at code-point xxxx.