Fix broken (panicking) RegExp transformations

Transformations would panic on some edge (error) cases:

    \u0z
    \x_
This commit is contained in:
Robert Krimen
2012-12-28 15:50:37 -08:00
parent de3300c23b
commit 668d0fc6a7
4 changed files with 25 additions and 33 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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")
}

View File

@@ -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)