aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2019-10-06 11:49:39 +0800
committerGitHub <noreply@github.com>2019-10-06 11:49:39 +0800
commit0a63f2f2b09251ad3f6b771dcf1ae1b4b9c921d7 (patch)
tree14c9b617a6ecfc292ab73a3db2be9cbf1f89faa6
parent931ac666382081a80267ab01ecfa5712162d5837 (diff)
downloadtracifyjs-0a63f2f2b09251ad3f6b771dcf1ae1b4b9c921d7.tar.gz
tracifyjs-0a63f2f2b09251ad3f6b771dcf1ae1b4b9c921d7.zip
workaround V8 RegExp bug (#3453)
fixes #3434
-rw-r--r--lib/output.js27
-rw-r--r--test/compress/regexp.js137
2 files changed, 159 insertions, 5 deletions
diff --git a/lib/output.js b/lib/output.js
index 2d0dc53f..af0cdc4b 100644
--- a/lib/output.js
+++ b/lib/output.js
@@ -136,8 +136,7 @@ function OutputStream(options) {
function make_string(str, quote) {
var dq = 0, sq = 0;
- str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g,
- function(s, i) {
+ str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s, i) {
switch (s) {
case '"': ++dq; return '"';
case "'": ++sq; return "'";
@@ -599,7 +598,6 @@ function OutputStream(options) {
}
print(encoded);
},
- encode_string : encode_string,
next_indent : next_indent,
with_indent : with_indent,
with_block : with_block,
@@ -1383,8 +1381,27 @@ function OutputStream(options) {
if (regexp.raw_source) {
str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/"));
}
- str = output.to_utf8(str);
- output.print(str);
+ output.print(output.to_utf8(str).replace(/\\(?:\0(?![0-9])|[^\0])/g, function(seq) {
+ switch (seq[1]) {
+ case "\n": return "\\n";
+ case "\r": return "\\r";
+ case "\t": return "\t";
+ case "\b": return "\b";
+ case "\f": return "\f";
+ case "\0": return "\0";
+ case "\x0B": return "\v";
+ case "\u2028": return "\\u2028";
+ case "\u2029": return "\\u2029";
+ default: return seq;
+ }
+ }).replace(/[\n\r\u2028\u2029]/g, function(c) {
+ switch (c) {
+ case "\n": return "\\n";
+ case "\r": return "\\r";
+ case "\u2028": return "\\u2028";
+ case "\u2029": return "\\u2029";
+ }
+ }));
var p = output.parent();
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
output.print(" ");
diff --git a/test/compress/regexp.js b/test/compress/regexp.js
index ac834e5d..6b93faba 100644
--- a/test/compress/regexp.js
+++ b/test/compress/regexp.js
@@ -35,3 +35,140 @@ regexp_2: {
}
expect_stdout: '["PASS","pass"]'
}
+
+issue_3434_1: {
+ options = {
+ evaluate: true,
+ unsafe: true,
+ }
+ beautify = {
+ beautify: true,
+ }
+ input: {
+ var o = {
+ "\n": RegExp("\n"),
+ "\r": RegExp("\r"),
+ "\t": RegExp("\t"),
+ "\b": RegExp("\b"),
+ "\f": RegExp("\f"),
+ "\0": RegExp("\0"),
+ "\x0B": RegExp("\x0B"),
+ "\u2028": RegExp("\u2028"),
+ "\u2029": RegExp("\u2029"),
+ };
+ for (var c in o)
+ console.log(o[c].test("\\"), o[c].test(c));
+ }
+ expect_exact: [
+ "var o = {",
+ ' "\\n": /\\n/,',
+ ' "\\r": /\\r/,',
+ ' "\\t": /\t/,',
+ ' "\\b": /\b/,',
+ ' "\\f": /\f/,',
+ ' "\\0": /\0/,',
+ ' "\\v": /\v/,',
+ ' "\\u2028": /\\u2028/,',
+ ' "\\u2029": /\\u2029/',
+ "};",
+ "",
+ 'for (var c in o) console.log(o[c].test("\\\\"), o[c].test(c));',
+ ]
+ expect_stdout: [
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ ]
+}
+
+issue_3434_2: {
+ options = {
+ evaluate: true,
+ unsafe: true,
+ }
+ beautify = {
+ beautify: true,
+ }
+ input: {
+ var o = {
+ "\n": RegExp("\\\n"),
+ "\r": RegExp("\\\r"),
+ "\t": RegExp("\\\t"),
+ "\b": RegExp("\\\b"),
+ "\f": RegExp("\\\f"),
+ "\0": RegExp("\\\0"),
+ "\x0B": RegExp("\\\x0B"),
+ "\u2028": RegExp("\\\u2028"),
+ "\u2029": RegExp("\\\u2029"),
+ };
+ for (var c in o)
+ console.log(o[c].test("\\"), o[c].test(c));
+ }
+ expect_exact: [
+ "var o = {",
+ ' "\\n": /\\n/,',
+ ' "\\r": /\\r/,',
+ ' "\\t": /\t/,',
+ ' "\\b": /\b/,',
+ ' "\\f": /\f/,',
+ ' "\\0": /\0/,',
+ ' "\\v": /\v/,',
+ ' "\\u2028": /\\u2028/,',
+ ' "\\u2029": /\\u2029/',
+ "};",
+ "",
+ 'for (var c in o) console.log(o[c].test("\\\\"), o[c].test(c));',
+ ]
+ expect_stdout: [
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ "false true",
+ ]
+}
+
+issue_3434_3: {
+ options = {
+ evaluate: true,
+ unsafe: true,
+ }
+ input: {
+ RegExp("\n");
+ RegExp("\r");
+ RegExp("\\n");
+ RegExp("\\\n");
+ RegExp("\\\\n");
+ RegExp("\\\\\n");
+ RegExp("\\\\\\n");
+ RegExp("\\\\\\\n");
+ RegExp("\u2028");
+ RegExp("\u2029");
+ RegExp("\n\r\u2028\u2029");
+ RegExp("\\\nfo\n[\n]o\\bbb");
+ }
+ expect: {
+ /\n/;
+ /\r/;
+ /\n/;
+ /\n/;
+ /\\n/;
+ /\\\n/;
+ /\\\n/;
+ /\\\n/;
+ /\u2028/;
+ /\u2029/;
+ /\n\r\u2028\u2029/;
+ /\nfo\n[\n]o\bbb/;
+ }
+}