mirror of
https://github.com/robertkrimen/otto.git
synced 2025-12-24 12:58:05 +08:00
Fix broken (panicking) RegExp transformations
Transformations would panic on some edge (error) cases:
\u0z
\x_
This commit is contained in:
2
Makefile
2
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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user