1
0
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:
Conrad Pankoff 2023-07-10 20:21:40 +10:00
parent 67dbb5d65b
commit fc4074c616
2 changed files with 63 additions and 1 deletions

View File

@ -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}
}

View File

@ -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)
}
})
}