Skip to content

Commit

Permalink
Reverted to the old behaviour of returning an error when converting n…
Browse files Browse the repository at this point in the history
…on-array values into slices. Fixes dop251#369, closes dop251#370.
  • Loading branch information
dop251 committed Jan 24, 2022
1 parent dd567e7 commit 61453c1
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 6 deletions.
6 changes: 5 additions & 1 deletion object.go
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,11 @@ func genericExportToArrayOrSlice(o *Object, dst reflect.Value, typ reflect.Type,
}
} else {
// array-like
l := toIntStrict(toLength(o.self.getStr("length", nil)))
lp := o.self.getStr("length", nil)
if lp == nil {
return fmt.Errorf("cannot convert %v to %v: not an array or iterable", o, typ)
}
l := toIntStrict(toLength(lp))
if dst.Len() != l {
if typ.Kind() == reflect.Array {
return fmt.Errorf("cannot convert an array-like object into an array, lengths mismatch (have %d, need %d)", l, dst.Len())
Expand Down
7 changes: 5 additions & 2 deletions object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,15 @@ func TestExportToSliceNonIterable(t *testing.T) {
o := vm.NewObject()
var a []interface{}
err := vm.ExportTo(o, &a)
if err != nil {
t.Fatal(err)
if err == nil {
t.Fatal("Expected an error")
}
if len(a) != 0 {
t.Fatalf("a: %v", a)
}
if msg := err.Error(); msg != "cannot convert [object Object] to []interface {}: not an array or iterable" {
t.Fatalf("Unexpected error: %v", err)
}
}

func ExampleRuntime_ExportTo_iterableToSlice() {
Expand Down
6 changes: 3 additions & 3 deletions runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -1863,7 +1863,7 @@ func (r *Runtime) wrapReflectFunc(value reflect.Value) func(FunctionCall) Value

// if this is a variadic Go function, and the caller has supplied
// exactly the number of JavaScript arguments required, and this
// is the last JavaScript argument, try treating the it as the
// is the last JavaScript argument, try treating it as the
// actual set of variadic Go arguments. if that succeeds, break
// out of the loop.
if typ.IsVariadic() && len(call.Arguments) == nargs && i == nargs-1 {
Expand All @@ -1877,7 +1877,7 @@ func (r *Runtime) wrapReflectFunc(value reflect.Value) func(FunctionCall) Value
v := reflect.New(t).Elem()
err := r.toReflectValue(a, v, &objectExportCtx{})
if err != nil {
panic(r.newError(r.global.TypeError, "could not convert function call parameter %v to %v", a, t))
panic(r.NewTypeError("could not convert function call parameter %d: %v", i, err))
}
in[i] = v
}
Expand Down Expand Up @@ -2195,7 +2195,7 @@ func (r *Runtime) wrapJSFunc(fn Callable, typ reflect.Type) func(args []reflect.
// If an object has a 'length' property it is treated as array-like. The resulting slice will contain
// obj[0], ... obj[length-1].
//
// Any other Object is treated as an array-like object with zero length and results in an empty slice.
// For any other Object an error is returned.
//
// Array types
//
Expand Down
16 changes: 16 additions & 0 deletions runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,22 @@ func TestSetGoFunc(t *testing.T) {
}
}

func TestSetFuncVariadic(t *testing.T) {
vm := New()
vm.Set("f", func(s string, g ...Value) {
something := g[0].ToObject(vm).Get(s).ToInteger()
if something != 5 {
t.Fatal()
}
})
_, err := vm.RunString(`
f("something", {something: 5})
`)
if err != nil {
t.Fatal(err)
}
}

func TestArgsKeys(t *testing.T) {
const SCRIPT = `
function testArgs2(x, y, z) {
Expand Down
1 change: 1 addition & 0 deletions value.go
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ func (o *Object) baseObject(*Runtime) *Object {
// For an array, returns its items as []interface{}.
//
// In all other cases returns own enumerable non-symbol properties as map[string]interface{}.
//
// This method will panic with an *Exception if a JavaScript exception is thrown in the process.
func (o *Object) Export() (ret interface{}) {
o.runtime.tryPanic(func() {
Expand Down

0 comments on commit 61453c1

Please sign in to comment.