Skip to content

Commit

Permalink
fix: regexp substring matches (#466)
Browse files Browse the repository at this point in the history
Set RegExp.input, RegExp.$_ and RegExp.$1 -> $9 substring matches on
successful match.

Fixes #317
  • Loading branch information
stevenh authored Nov 28, 2022
1 parent 3697ad1 commit c745096
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 1 deletion.
35 changes: 34 additions & 1 deletion builtin_regexp.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,40 @@ func builtinRegExp_exec(call FunctionCall) Value {
func builtinRegExp_test(call FunctionCall) Value {
thisObject := call.thisObject()
target := call.Argument(0).string()
match, _ := execRegExp(thisObject, target)
match, result := execRegExp(thisObject, target)

if !match {
return toValue_bool(match)
}

// Match extract and assign input, $_ and $1 -> $9 on global RegExp.
input := toValue_string(target)
call.runtime.global.RegExp.defineProperty("$_", input, 0100, false)
call.runtime.global.RegExp.defineProperty("input", input, 0100, false)

var start int
n := 1
re := call.runtime.global.RegExp
for i, v := range result[2:] {
if i%2 == 0 {
start = v
} else {
re.defineProperty(fmt.Sprintf("$%d", n), toValue_string(target[start:v]), 0100, false)
n++
if n == 10 {
break
}
}
}

if n <= 9 {
// Erase remaining.
empty := toValue_string("")
for i := n; i <= 9; i++ {
re.defineProperty(fmt.Sprintf("$%d", i), empty, 0100, false)
}
}

return toValue_bool(match)
}

Expand Down
57 changes: 57 additions & 0 deletions issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1017,3 +1017,60 @@ func Test_issue329(t *testing.T) {
require.NoError(t, err)
require.Equal(t, uint32(6), length)
}

func Test_issue317(t *testing.T) {
vm := New()
tests := map[string]struct {
input string
regexp string
want string
}{
"match-all": {
input: "all-11-22-33-44-55-66-77-88-99-XX",
regexp: "(1+)-(2+)-(3+)-(4+)-(5+)-(6+)-(7+)-(8+)-(9+)-(X+)",
want: "all-11-22-33-44-55-66-77-88-99-XX,11,22,33,44,55,66,77,88,99",
},
"match-partial": {
input: "partial-11-22-33-44-55-66-77-88-99-XX",
regexp: "(1+)-(2+)-(3+)-(4+)-(5+)",
want: "partial-11-22-33-44-55-66-77-88-99-XX,11,22,33,44,55,,,,",
},
"no-match": {
input: "no-22-33-44-55-66-77-88-99-XX",
regexp: "(1+)-(2+)-(3+)-(4+)-(5+)-(6+)-(7+)-(8+)-(9+)-(X+)",
want: "",
},
}

previous := ",,,,,,,,,"
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
err := vm.Set("val", tt.input)
require.NoError(t, err)

err = vm.Set("regexp", tt.regexp)
require.NoError(t, err)

val, err := vm.Run(`
var parts = [];
new RegExp(regexp).test(val);
parts.push(
RegExp.$_, RegExp.$1, RegExp.$2, RegExp.$3, RegExp.$4,
RegExp.$5, RegExp.$6, RegExp.$7, RegExp.$8, RegExp.$9
);
parts.join(",");
`)
require.NoError(t, err)

// If no match occurs the previous values will remain.
if tt.want == "" {
tt.want = previous
}
previous = tt.want

exp, err := val.Export()
require.NoError(t, err)
require.Equal(t, tt.want, exp)
})
}
}

0 comments on commit c745096

Please sign in to comment.