Skip to content

Commit

Permalink
JS: fix bugs related to the 'use strict' directive prologues at the b…
Browse files Browse the repository at this point in the history
…eginning of functions and modules, fixes #376
  • Loading branch information
tdewolff committed Feb 9, 2021
1 parent b5f25ca commit eb145d6
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 26 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module github.com/tdewolff/minify/v2

go 1.13

replace github.com/tdewolff/parse/v2 => ../parse

require (
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 // indirect
github.com/dustin/go-humanize v1.0.0
Expand Down
3 changes: 3 additions & 0 deletions js/js.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,9 @@ func (m *jsMinifier) minifyStmt(i js.IStmt) {
}
m.requireSemicolon()
}
case *js.DirectivePrologueStmt:
m.write(stmt.Value)
m.requireSemicolon()
}
}

Expand Down
47 changes: 24 additions & 23 deletions js/js_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,29 +126,29 @@ func TestJS(t *testing.T) {
{`try {a} finally {c}`, `try{a}finally{c}`},
{`a=b;c=d`, `a=b,c=d`},

// strings
{`""`, `""`},
{`"\x7"`, `"\x7"`},
{`"string\'string"`, `"string'string"`},
{`'string\"string'`, `'string"string'`},
{`'string\t\f\v\bstring'`, "'string\t\f\v\bstring'"},
{`"string\a\c\'string"`, `"stringac'string"`},
{`"string\∀string"`, `"string∀string"`},
{`"string\0\uFFFFstring"`, `"string\0\uFFFFstring"`},
{`"string\x00\x55\x0A\x0D\x22\x27string"`, `"string\0U\n\r\"'string"`},
{`"string\000\12\015\042\47\411string"`, `"string\0\n\r\"'!1string"`},
{"'string\\n\\rstring'", "'string\\n\\rstring'"},
{"'string\\\r\nstring\\\nstring\\\rstring\\\u2028string\\\u2029string'", "'stringstringstringstringstringstring'"},
{`"str1ng" + "str2ng"`, `"str1ngstr2ng"`},
{`"str1ng" + "str2ng" + "str3ng"`, `"str1ngstr2ngstr3ng"`},
{`"padding" + this`, `"padding"+this`},
{`"<\/script>"`, `"<\/script>"`},
{`"</scr"+"ipt>"`, `"<\/script>"`},
{`"\""`, `'"'`},
{`'\'""'`, `'\'""'`},
{`"\"\"a'"`, `'""a\''`},
{`"'" + '"'`, `"'\""`},
{`'"' + "'"`, `'"\''`},
// strings (prepend '0,' to avoid being a directive prologue)
{`0,""`, `0,""`},
{`0,"\x7"`, `0,"\x7"`},
{`0,"string\'string"`, `0,"string'string"`},
{`0,'string\"string'`, `0,'string"string'`},
{`0,'string\t\f\v\bstring'`, "0,'string\t\f\v\bstring'"},
{`0,"string\a\c\'string"`, `0,"stringac'string"`},
{`0,"string\∀string"`, `0,"string∀string"`},
{`0,"string\0\uFFFFstring"`, `0,"string\0\uFFFFstring"`},
{`0,"string\x00\x55\x0A\x0D\x22\x27string"`, `0,"string\0U\n\r\"'string"`},
{`0,"string\000\12\015\042\47\411string"`, `0,"string\0\n\r\"'!1string"`},
{"0,'string\\n\\rstring'", "0,'string\\n\\rstring'"},
{"0,'string\\\r\nstring\\\nstring\\\rstring\\\u2028string\\\u2029string'", "0,'stringstringstringstringstringstring'"},
{`0,"str1ng" + "str2ng"`, `0,"str1ngstr2ng"`},
{`0,"str1ng" + "str2ng" + "str3ng"`, `0,"str1ngstr2ngstr3ng"`},
{`0,"padding" + this`, `0,"padding"+this`},
{`0,"<\/script>"`, `0,"<\/script>"`},
{`0,"</scr"+"ipt>"`, `0,"<\/script>"`},
{`0,"\""`, `0,'"'`},
{`0,'\'""'`, `0,'\'""'`},
{`0,"\"\"a'"`, `0,'""a\''`},
{`0,"'" + '"'`, `0,"'\""`},
{`0,'"' + "'"`, `0,'"\''`},

// rename true, false, undefined, Infinity
{`x=true`, `x=!0`},
Expand Down Expand Up @@ -312,6 +312,7 @@ func TestJS(t *testing.T) {
{`var a;var {}=b;`, `var a;{}=b`},
{`"use strict";var a;var b;b=5`, `"use strict";var b=5,a`},
{`"use strict";z+=6;var a;var b;b=5`, `"use strict";var a,b;z+=6,b=5`},
{`!function(){"use strict";return a}`, `!function(){"use strict";return a}`},

// function and method declarations
{`function g(){return}`, `function g(){}`},
Expand Down
8 changes: 5 additions & 3 deletions js/vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,11 @@ func (m *jsMinifier) hoistVars(body *js.BlockStmt) *js.VarDecl {

// ignore "use strict"
declStart := 0
if expr, ok := body.List[0].(*js.ExprStmt); ok {
if lit, ok := expr.Value.(*js.LiteralExpr); ok && lit.TokenType == js.StringToken && bytes.Equal(lit.Data, useStrictBytes) {
declStart = 1
for {
if _, ok := body.List[declStart].(*js.DirectivePrologueStmt); ok {
declStart++
} else {
break
}
}

Expand Down

0 comments on commit eb145d6

Please sign in to comment.