From 9145984972756c8b17f7edaf4d6e2391cb3fef65 Mon Sep 17 00:00:00 2001 From: Taco de Wolff Date: Sun, 14 May 2023 19:24:43 -0400 Subject: [PATCH] JS: use literal NULL instead of escaped zero in strings, fixes #577 --- js/js_test.go | 9 +++++---- js/util.go | 13 +++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/js/js_test.go b/js/js_test.go index 909266ac85..4ea670efea 100644 --- a/js/js_test.go +++ b/js/js_test.go @@ -149,9 +149,9 @@ func TestJS(t *testing.T) { {`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\0\uFFFFstring"`, "0,\"string\x00\\uFFFFstring\""}, + {`0,"string\x00\x55\x0A\x0D\x22\x27string"`, "0,\"string\x00U\\n\\r\\\"'string\""}, + {`0,"string\000\12\015\042\47\411string"`, "0,\"string\x00\\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"`}, @@ -793,7 +793,8 @@ func TestJS(t *testing.T) { {`var a=5;({});var b=class{c(){3}}`, `var b,a=5;({},b=class{c(){3}})`}, // #494 {`({});a={b(){3}}`, `({},a={b(){3}})`}, // #494 {`export default function Foo(){a}Foo.prototype.bar=b`, `export default function Foo(){a}Foo.prototype.bar=b`}, // #525 - {`(e=1,e=2)`, `e=1,e=2`}, // #528 + {`(e=1,e=2)`, `e=1,e=2`}, // #528 + {`"\x00\x31 \0"`, "\"\x001 \x00\""}, // #577 } m := minify.New() diff --git a/js/util.go b/js/util.go index c7e603cc51..585f32ef1d 100644 --- a/js/util.go +++ b/js/util.go @@ -981,12 +981,12 @@ func replaceEscapes(b []byte, quote byte, prefix, suffix int) []byte { for i := prefix; i < len(b)-suffix; i++ { if c := b[i]; c == '\\' { c = b[i+1] - if c == quote || c == '\\' || c == 'u' || c == '0' && (i+2 == len(b)-1 || b[i+2] < '0' || '7' < b[i+2]) || quote != '`' && (c == 'n' || c == 'r') { + if c == quote || c == '\\' || c == 'u' || quote != '`' && (c == 'n' || c == 'r') { // keep escape sequence i++ continue } - n := 1 + n := 1 // number of characters to skip if c == '\n' || c == '\r' || c == 0xE2 && i+3 < len(b)-1 && b[i+2] == 0x80 && (b[i+3] == 0xA8 || b[i+3] == 0xA9) { // line continuations if c == 0xE2 { @@ -1001,10 +1001,8 @@ func replaceEscapes(b []byte, quote byte, prefix, suffix int) []byte { // hexadecimal escapes _, _ = hex.Decode(b[i+3:i+4:i+4], b[i+2:i+4]) n = 3 - if b[i+3] == 0 || b[i+3] == '\\' || b[i+3] == quote || b[i+3] == '\n' || b[i+3] == '\r' { - if b[i+3] == 0 { - b[i+3] = '0' - } else if b[i+3] == '\n' { + if b[i+3] == '\\' || b[i+3] == quote || b[i+3] == '\n' || b[i+3] == '\r' { + if b[i+3] == '\n' { b[i+3] = 'n' } else if b[i+3] == '\r' { b[i+3] = 'r' @@ -1016,6 +1014,9 @@ func replaceEscapes(b []byte, quote byte, prefix, suffix int) []byte { i++ continue } + } else if c == '0' && (i+2 == len(b)-1 || b[i+2] < '0' || '7' < b[i+2]) { + // \0 (NULL) + b[i+1] = '\x00' } else if '0' <= c && c <= '7' { // octal escapes (legacy), \0 already handled num := c - '0'