mirror of
https://github.com/robertkrimen/otto
synced 2025-10-12 20:27:30 +08:00
fix: panic related to invalid property access in goMapObject
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
This commit is contained in:
parent
67dbb5d65b
commit
fc4074c616
|
@ -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}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user