Skip to content

Commit 7d084bf

Browse files
authored
Merge branch 'master' into fix/issue-836
2 parents 8956ee2 + f493d7d commit 7d084bf

5 files changed

Lines changed: 59 additions & 8 deletions

File tree

checker/checker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ func (v *Checker) binaryNode(node *ast.BinaryNode) Nature {
462462
return v.error(node, err.Error())
463463
}
464464
}
465-
if l.IsString() && r.IsString() {
465+
if (l.IsString() || l.IsByteSlice()) && r.IsString() {
466466
return v.config.NtCache.FromType(boolType)
467467
}
468468
if l.MaybeCompatible(&v.config.NtCache, r, StringCheck) {

checker/nature/nature.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ import (
1010
)
1111

1212
var (
13-
intType = reflect.TypeOf(0)
14-
floatType = reflect.TypeOf(float64(0))
15-
arrayType = reflect.TypeOf([]any{})
16-
timeType = reflect.TypeOf(time.Time{})
17-
durationType = reflect.TypeOf(time.Duration(0))
13+
intType = reflect.TypeOf(0)
14+
floatType = reflect.TypeOf(float64(0))
15+
arrayType = reflect.TypeOf([]any{})
16+
byteSliceType = reflect.TypeOf([]byte{})
17+
timeType = reflect.TypeOf(time.Time{})
18+
durationType = reflect.TypeOf(time.Duration(0))
1819

1920
builtinInt = map[reflect.Type]struct{}{
2021
reflect.TypeOf(int(0)): {},
@@ -502,6 +503,10 @@ func (n *Nature) IsString() bool {
502503
return n.Kind == reflect.String
503504
}
504505

506+
func (n *Nature) IsByteSlice() bool {
507+
return n.Type == byteSliceType
508+
}
509+
505510
func (n *Nature) IsArray() bool {
506511
return n.Kind == reflect.Slice || n.Kind == reflect.Array
507512
}

test/issues/854/issue_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/expr-lang/expr"
7+
"github.com/expr-lang/expr/internal/testify/require"
8+
"github.com/expr-lang/expr/types"
9+
)
10+
11+
func TestIssue854(t *testing.T) {
12+
envType := types.Map{
13+
"user": types.Map{
14+
// If we do not specify `Profile` here,
15+
// this is a correct behavior to throw
16+
// on a missing property.
17+
},
18+
}
19+
20+
code := `user.Profile?.Address ?? "Unknown address"`
21+
22+
_, err := expr.Compile(code, expr.Env(envType))
23+
require.Error(t, err)
24+
}

vm/vm.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,13 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
299299
vm.push(false)
300300
break
301301
}
302-
match, err := regexp.MatchString(b.(string), a.(string))
302+
var match bool
303+
var err error
304+
if s, ok := a.(string); ok {
305+
match, err = regexp.MatchString(b.(string), s)
306+
} else {
307+
match, err = regexp.Match(b.(string), a.([]byte))
308+
}
303309
if err != nil {
304310
panic(err)
305311
}
@@ -312,7 +318,11 @@ func (vm *VM) Run(program *Program, env any) (_ any, err error) {
312318
break
313319
}
314320
r := program.Constants[arg].(*regexp.Regexp)
315-
vm.push(r.MatchString(a.(string)))
321+
if s, ok := a.(string); ok {
322+
vm.push(r.MatchString(s))
323+
} else {
324+
vm.push(r.Match(a.([]byte)))
325+
}
316326

317327
case OpContains:
318328
b := vm.pop()

vm/vm_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,18 @@ func TestVM_OpcodeOperations(t *testing.T) {
368368
expr: `"hello123" matches "^hello\\d+$"`,
369369
want: true,
370370
},
371+
{
372+
name: "byte slice matches regex",
373+
expr: `b matches "^hello\\d+$"`,
374+
env: map[string]any{"b": []byte("hello123")},
375+
want: true,
376+
},
377+
{
378+
name: "byte slice matches dynamic regex",
379+
expr: `b matches pattern`,
380+
env: map[string]any{"b": []byte("hello123"), "pattern": "^hello\\d+$"},
381+
want: true,
382+
},
371383

372384
// Data Structure Operations
373385
{

0 commit comments

Comments
 (0)