Skip to content

Commit

Permalink
JS: fix more bugs with string/template literals and newlines, see #653
Browse files Browse the repository at this point in the history
  • Loading branch information
tdewolff committed Jan 6, 2024
1 parent 55d52d2 commit e00409b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 12 deletions.
2 changes: 0 additions & 2 deletions js/js_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,6 @@ func TestJS(t *testing.T) {
{`"string\0\uFFFFstring"`, "\"string\\0\uffffstring\""},
{`"string\x00\x55\x0A\x0D\x22\x27string"`, "`string\\x00U\n\r\"'string`"},
{`"string\000\12\015\042\47\411string"`, "\"string\\0\\n\\r\\\"'!1string\""},
{`'\x0A\x0D'`, "`\n\r`"},
{`'\12\15'`, `"\n\r"`},
{`"\x005"`, `"\x005"`},
{"'string\\n\\rstring'", "`string\n\rstring`"},
{"'string\\\r\nstring\\\nstring\\\rstring\\\u2028string\\\u2029string'", `"stringstringstringstringstringstring"`},
Expand Down
12 changes: 8 additions & 4 deletions js/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -948,13 +948,17 @@ func minifyString(b []byte, allowTemplate bool) []byte {
doubleQuotes++
} else if b[i] == '`' {
backtickQuotes++
} else if b[i] == '$' {
} else if b[i] == '$' && i+1 < len(b) && b[i+1] == '{' {
dollarSigns++
} else if b[i] == '\\' && i+1 < len(b) {
if b[i+1] == 'n' || b[i+1] == 'r' {
newlines++
} else if '1' <= b[i+1] && b[i+1] <= '9' || b[i+1] == '0' && i+2 < len(b) && '0' <= b[i+2] && b[i+2] <= '9' {
hasOctals = true
if i+2 < len(b) && b[i+1] == '1' && (b[i+2] == '2' || b[i+2] == '5') {
newlines++
} else {
hasOctals = true
}
} else if b[i+1] == 'x' && i+3 < len(b) && b[i+2] == '0' && (b[i+3]|0x20 == 'a' || b[i+3]|0x20 == 'd') {
newlines++
} else if b[i+1] == 'u' && i+5 < len(b) && b[i+2] == '0' && b[i+3] == '0' && b[i+4] == '0' && (b[i+5]|0x20 == 'a' || b[i+5]|0x20 == 'd') {
Expand Down Expand Up @@ -995,7 +999,7 @@ func replaceEscapes(b []byte, quote byte, prefix, suffix int) []byte {
for i := prefix; i < len(b)-suffix-1; i++ {
if c := b[i]; c == '\\' {
c = b[i+1]
if c == quote || c == '\\' || c == '0' && (len(b)-suffix <= i+2 || b[i+2] < '0' || '7' < b[i+2]) {
if c == quote || c == '\\' || quote != '`' && (c == 'n' || c == 'r') || c == '0' && (len(b)-suffix <= i+2 || b[i+2] < '0' || '7' < b[i+2]) {
// keep escape sequence
i++
continue
Expand Down Expand Up @@ -1106,7 +1110,7 @@ func replaceEscapes(b []byte, quote byte, prefix, suffix int) []byte {
}
}
b[i] = num
if num == 0 || num == '\\' || num == quote || num == '\n' || num == '\r' {
if num == 0 || num == '\\' || num == quote || quote != '`' && (num == '\n' || num == '\r') {
if num == 0 {
b[i+1] = '0'
} else if num == '\n' {
Expand Down
32 changes: 26 additions & 6 deletions js/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,32 @@ func TestHexadecimalNumber(t *testing.T) {
}

func TestString(t *testing.T) {
test.Bytes(t, minifyString([]byte(`""`), true), []byte(`""`))
test.Bytes(t, minifyString([]byte(`"abc"`), true), []byte(`"abc"`))
test.Bytes(t, minifyString([]byte(`'abc'`), true), []byte(`"abc"`))
test.Bytes(t, minifyString([]byte(`"\8\9\t"`), true), []byte("\"89\t\""))
test.Bytes(t, minifyString([]byte(`"\12"`), true), []byte(`"\n"`))
test.Bytes(t, minifyString([]byte(`"\n\r$"`), true), []byte("`\n\r$`"))
tests := []struct {
str, expected string
}{
{`""`, `""`},
{`"abc"`, `"abc"`},
{`'abc'`, `"abc"`},
{`"\8\9\t"`, "\"89\t\""},
{`"\n\r"`, "`\n\r`"},
{`"\12\15"`, "`\n\r`"},
{`"\x0A\x0D"`, "`\n\r`"},
{`"\u000A\u000D"`, "`\n\r`"},
{`"\u{A}\u{D}"`, "`\n\r`"},
{`"\n$"`, "`\n$`"},
{`"\n${"`, `"\n${"`},
{`"\n\r${${"`, `"\n\r${${"`},
{`"\12\15${${"`, `"\n\r${${"`},
{`"\x0A\x0D${${"`, `"\n\r${${"`},
{`"\u000A\u000D${${"`, `"\n\r${${"`},
{`"\u{A}\u{D}${${"`, `"\n\r${${"`},
}

for _, tt := range tests {
t.Run(tt.str, func(t *testing.T) {
test.Bytes(t, minifyString([]byte(tt.str), true), []byte(tt.expected))
})
}
}

func TestHasSideEffects(t *testing.T) {
Expand Down

0 comments on commit e00409b

Please sign in to comment.