diff --git a/Makefile b/Makefile index 76b8da4..f09742c 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,8 @@ TEST := -v --run RegExp TEST := -v --run stringToFloat TEST := -v --run TryFinally TEST := -v --run RegExp_exec +TEST := -v --run _panic +TEST := -v --run TransformRegExp TEST := . test: test-i diff --git a/otto_test.go b/otto_test.go index f8a38e2..66233bb 100644 --- a/otto_test.go +++ b/otto_test.go @@ -58,6 +58,7 @@ func TestTransformRegExp(t *testing.T) { Is(transformRegExp(`\\|'|\r|\n|\t|\u2028|\u2029`), `\\|'|\r|\n|\t|\x{2028}|\x{2029}`) Is(transformRegExp(`\x`), `x`) + Is(transformRegExp(`\u0z01\x\undefined`), `u0z01xundefined`) } func TestIsValidRegExp(t *testing.T) { diff --git a/panic_test.go b/panic_test.go index fd03c21..0f4492c 100644 --- a/panic_test.go +++ b/panic_test.go @@ -23,7 +23,13 @@ func Test_panic(t *testing.T) { // without panic test(` var abc = 0x0410; - var def = String.fromCharCode(abc) - new RegExp("\\c" + def).exec(def) + var def = String.fromCharCode(abc); + new RegExp("\\c" + def).exec(def); `, "null") + + // Test transforming a transformable regular expression without a panic + test(` + new RegExp("\\u0000"); + new RegExp("\\undefined").test("undefined"); + `, "true") } diff --git a/type_regexp.go b/type_regexp.go index cafd5c8..fc9dba1 100644 --- a/type_regexp.go +++ b/type_regexp.go @@ -128,9 +128,8 @@ func execResultToArray(runtime *_runtime, target string, result []int) *_object var transformRegExp_matchSlashU = regexp.MustCompile(`\\u([[:xdigit:]]{1,4})`) var transformRegExp_escape_c = regexp.MustCompile(`\\c([A-Za-z])`) var transformRegExp_unescape_c = regexp.MustCompile(`\\c`) -var transformRegExp_unescape = regexp.MustCompile(strings.NewReplacer("\n", "", "\t", "", " ", "").Replace(` - - (?: +var transformRegExp_unescape = []*regexp.Regexp{ + regexp.MustCompile(strings.NewReplacer("\n", "", "\t", "", " ", "").Replace(` \\( [ \x{0043}\x{0045}-\x{004F} @@ -140,40 +139,24 @@ var transformRegExp_unescape = regexp.MustCompile(strings.NewReplacer("\n", "", \x{0080}-\x{FFFF} ] )() - ) | - (?: - \\(u)([^[:xdigit:]]) - ) | - (?: - \\(u)([:xdigit:][^[:xdigit:]]) - ) | - (?: - \\(u)([:xdigit:][:xdigit:][^[:xdigit:]]) - ) | - (?: - \\(u)([:xdigit:][:xdigit:][:xdigit:][^[:xdigit:]]) - ) | - (?: - \\(x)([^[:xdigit:]]) - ) | - (?: - \\(x)([:xdigit:][^[:xdigit:]]) - ) + `)), + regexp.MustCompile(`\\(u)([^[:xdigit:]])`), + regexp.MustCompile(`\\(u)([[:xdigit:]][^[:xdigit:]])`), + regexp.MustCompile(`\\(u)([[:xdigit:]][[:xdigit:]][^[:xdigit:]])`), + regexp.MustCompile(`\\(u)([[:xdigit:]][[:xdigit:]][[:xdigit:]][^[:xdigit:]])`), + regexp.MustCompile(`\\(x)([^[:xdigit:]])`), + regexp.MustCompile(`\\(x)([[:xdigit:]][^[:xdigit:]])`), +} -`)) -var transformRegExp_unescapeDollar = regexp.MustCompile(strings.NewReplacer("\n", "", "\t", "", " ", "").Replace(` - - (?: - \\([cux])$ - ) - -`)) +var transformRegExp_unescapeDollar = regexp.MustCompile(`\\([cux])$`) // TODO Go "regexp" bug? Can't do: (?:)|(?:$) func transformRegExp(ecmaRegExp string) (goRegExp string) { // https://bugzilla.mozilla.org/show_bug.cgi/show_bug.cgi?id=334158 tmp := []byte(ecmaRegExp) - tmp = transformRegExp_unescape.ReplaceAll(tmp, []byte(`$1$2`)) + for _, value := range transformRegExp_unescape { + tmp = value.ReplaceAll(tmp, []byte(`$1$2`)) + } tmp = transformRegExp_escape_c.ReplaceAllFunc(tmp, func(in []byte) []byte{ in = bytes.ToUpper(in) return []byte(fmt.Sprintf("\\%o", in[0] - 64)) // \cA => \001 (A == 65)