Skip to content

Commit

Permalink
fix: panic related to invalid property access in goMapObject
Browse files Browse the repository at this point in the history
Ignore errors when converting a property name to the key type for goMapObject
during a getOwnProperty operation, as a property which fails conversion to the
target's key type could not possibly be a member of it.

fixes #488
  • Loading branch information
deoxxa committed Jul 10, 2023
1 parent 67dbb5d commit fc4074c
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
16 changes: 15 additions & 1 deletion type_go_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,21 @@ func (o goMapObject) toValue(value Value) reflect.Value {

func goMapGetOwnProperty(obj *object, name string) *property {
goObj := obj.value.(*goMapObject)
value := goObj.value.MapIndex(goObj.toKey(name))

// an error here means that the key referenced by `name` could not possibly
// be a property of this object, so it should be safe to ignore this error
//
// TODO: figure out if any cases from
// https://go.dev/ref/spec#Comparison_operators meet the criteria of 1)
// being possible to represent as a string, 2) being possible to reconstruct
// from a string, and 3) having a meaningful failure case in this context
// other than "key does not exist"
key, err := stringToReflectValue(name, goObj.keyType.Kind())
if err != nil {
return nil
}

value := goObj.value.MapIndex(key)
if value.IsValid() {
return &property{obj.runtime.toValue(value.Interface()), 0o111}
}
Expand Down
48 changes: 48 additions & 0 deletions value_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,42 @@ func TestToValue(t *testing.T) {
value, _ = vm.ToValue(&tmp2)
is(value, "undefined")
}

{
m := map[int64]string{0: "foo", 1: "bar"}
value, err := vm.ToValue(m)
is(err, nil)
v0, err := value.Object().Get("0")
is(err, nil)
is(v0, m[0])
v1, err := value.Object().Get("1")
is(err, nil)
is(v1, m[1])
missing, err := value.Object().Get("2")
is(err, nil)
is(missing, UndefinedValue())
invalid, err := value.Object().Get("xxx")
is(err, nil)
is(invalid, UndefinedValue())
}

{
m := map[uint64]string{0: "foo", 1: "bar"}
value, err := vm.ToValue(m)
is(err, nil)
v0, err := value.Object().Get("0")
is(err, nil)
is(v0, m[0])
v1, err := value.Object().Get("1")
is(err, nil)
is(v1, m[1])
missing, err := value.Object().Get("2")
is(err, nil)
is(missing, UndefinedValue())
invalid, err := value.Object().Get("xxx")
is(err, nil)
is(invalid, UndefinedValue())
}
})
}

Expand Down Expand Up @@ -295,6 +331,18 @@ func TestExport(t *testing.T) {
vm.Set("abc", abc)
is(test(`abc;`).export(), abc)
}

{
abc := map[int64]string{0: "foo", 1: "bar"}
vm.Set("abc", abc)
is(test(`abc;`).export(), abc)
}

{
abc := map[uint64]string{0: "foo", 1: "bar"}
vm.Set("abc", abc)
is(test(`abc;`).export(), abc)
}
})
}

Expand Down

0 comments on commit fc4074c

Please sign in to comment.