From 4d7746baf31405427209de0d8c44d9c8263a2563 Mon Sep 17 00:00:00 2001 From: Anthony Van de Gejuchte Date: Fri, 20 May 2016 10:25:35 +0200 Subject: Throw errors in strict mode for octal strings Adds a directive tracker for the parser/tokenizer to allow parsing depending on directive context. --- test/mocha/directives.js | 61 ++++++++++++++++++++++++++++++++++++++++++++ test/mocha/string-literal.js | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 test/mocha/directives.js (limited to 'test/mocha') diff --git a/test/mocha/directives.js b/test/mocha/directives.js new file mode 100644 index 00000000..4433e429 --- /dev/null +++ b/test/mocha/directives.js @@ -0,0 +1,61 @@ +var assert = require("assert"); +var uglify = require("../../"); + +describe("Directives", function() { + it ("Should allow tokenizer to store directives state", function() { + var tokenizer = uglify.tokenizer("", "foo.js"); + + // Stack level 0 + assert.strictEqual(tokenizer.has_directive("use strict"), false); + assert.strictEqual(tokenizer.has_directive("use asm"), false); + assert.strictEqual(tokenizer.has_directive("use thing"), false); + + // Stack level 2 + tokenizer.push_directives_stack(); + tokenizer.push_directives_stack(); + tokenizer.add_directive("use strict"); + assert.strictEqual(tokenizer.has_directive("use strict"), true); + assert.strictEqual(tokenizer.has_directive("use asm"), false); + assert.strictEqual(tokenizer.has_directive("use thing"), false); + + // Stack level 3 + tokenizer.push_directives_stack(); + tokenizer.add_directive("use strict"); + tokenizer.add_directive("use asm"); + assert.strictEqual(tokenizer.has_directive("use strict"), true); + assert.strictEqual(tokenizer.has_directive("use asm"), true); + assert.strictEqual(tokenizer.has_directive("use thing"), false); + + // Stack level 2 + tokenizer.pop_directives_stack(); + assert.strictEqual(tokenizer.has_directive("use strict"), true); + assert.strictEqual(tokenizer.has_directive("use asm"), false); + assert.strictEqual(tokenizer.has_directive("use thing"), false); + + // Stack level 3 + tokenizer.push_directives_stack(); + tokenizer.add_directive("use thing"); + tokenizer.add_directive("use\\\nasm"); + assert.strictEqual(tokenizer.has_directive("use strict"), true); + assert.strictEqual(tokenizer.has_directive("use asm"), false); // Directives are strict! + assert.strictEqual(tokenizer.has_directive("use thing"), true); + + // Stack level 2 + tokenizer.pop_directives_stack(); + assert.strictEqual(tokenizer.has_directive("use strict"), true); + assert.strictEqual(tokenizer.has_directive("use asm"), false); + assert.strictEqual(tokenizer.has_directive("use thing"), false); + + // Stack level 1 + tokenizer.pop_directives_stack(); + assert.strictEqual(tokenizer.has_directive("use strict"), false); + assert.strictEqual(tokenizer.has_directive("use asm"), false); + assert.strictEqual(tokenizer.has_directive("use thing"), false); + + // Stack level 0 + tokenizer.pop_directives_stack(); + assert.strictEqual(tokenizer.has_directive("use strict"), false); + assert.strictEqual(tokenizer.has_directive("use asm"), false); + assert.strictEqual(tokenizer.has_directive("use thing"), false); + }); +}); \ No newline at end of file diff --git a/test/mocha/string-literal.js b/test/mocha/string-literal.js index 84aaad7e..c54c161c 100644 --- a/test/mocha/string-literal.js +++ b/test/mocha/string-literal.js @@ -31,4 +31,51 @@ describe("String literals", function() { var output = UglifyJS.parse('var a = "a\\\nb";').print_to_string(); assert.equal(output, 'var a="ab";'); }); + + it("Should throw error in strict mode if string contains escaped octalIntegerLiteral", function() { + var inputs = [ + '"use strict";\n"\\76";', + '"use strict";\nvar foo = "\\76";', + '"use strict";\n"\\1";', + '"use strict";\n"\\07";', + '"use strict";\n"\\011"' + ]; + + var test = function(input) { + return function() { + var output = UglifyJS.parse(input); + } + }; + + var error = function(e) { + return e instanceof UglifyJS.JS_Parse_Error && + e.message === "Octal literals are not allowed in strict mode"; + } + + for (var input in inputs) { + assert.throws(test(inputs[input]), error); + } + }); + + it("Should not throw error outside strict mode if string contains escaped octalIntegerLiteral", function() { + var tests = [ + ['"\\76";', '">";'], + ['"\\0"', '"\\x00";'], + ['"\\08"', '"\\x008";'], + ['"\\008"', '"\\x008";'], + ['"\\0008"', '"\\x008";'], + ['"use strict" === "use strict";\n"\\76";', '"use strict"==="use strict";">";'], + // ['"use\\\n strict";\n"\\07";', '"use\\\n strict";\n"\\u0007";'] // TODO No way to store this content literally yet as directive + ]; + + for (var test in tests) { + var output = UglifyJS.parse(tests[test][0]).print_to_string(); + assert.equal(output, tests[test][1]); + } + }); + + it("Should not throw error when digit is 8 or 9", function() { + assert.equal(UglifyJS.parse('"use strict";"\\08"').print_to_string(), '"use strict";"\\x008";'); + assert.equal(UglifyJS.parse('"use strict";"\\09"').print_to_string(), '"use strict";"\\x009";'); + }); }); \ No newline at end of file -- cgit v1.2.3