Skip to content

Commit

Permalink
Always create a map when exporting. Fixes dop251#422.
Browse files Browse the repository at this point in the history
  • Loading branch information
dop251 committed Aug 5, 2022
1 parent 7adb499 commit fdb999e
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 6 deletions.
4 changes: 1 addition & 3 deletions builtin_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ func (mo *mapObject) export(ctx *objectExportCtx) interface{} {
}

func (mo *mapObject) exportToMap(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
if dst.IsNil() {
dst.Set(reflect.MakeMap(typ))
}
dst.Set(reflect.MakeMap(typ))
ctx.putTyped(mo.val, typ, dst.Interface())
keyTyp := typ.Key()
elemTyp := typ.Elem()
Expand Down
40 changes: 40 additions & 0 deletions builtin_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,46 @@ func TestMapEvilIterator(t *testing.T) {
testScriptWithTestLib(SCRIPT, _undefined, t)
}

func TestMapExportToNilMap(t *testing.T) {
vm := New()
var m map[int]interface{}
res, err := vm.RunString("new Map([[1, true]])")
if err != nil {
t.Fatal(err)
}
err = vm.ExportTo(res, &m)
if err != nil {
t.Fatal(err)
}
if len(m) != 1 {
t.Fatal(m)
}
if _, exists := m[1]; !exists {
t.Fatal(m)
}
}

func TestMapExportToNonNilMap(t *testing.T) {
vm := New()
m := map[int]interface{}{
2: true,
}
res, err := vm.RunString("new Map([[1, true]])")
if err != nil {
t.Fatal(err)
}
err = vm.ExportTo(res, &m)
if err != nil {
t.Fatal(err)
}
if len(m) != 1 {
t.Fatal(m)
}
if _, exists := m[1]; !exists {
t.Fatal(m)
}
}

func ExampleObject_Export_map() {
vm := New()
m, err := vm.RunString(`
Expand Down
1 change: 1 addition & 0 deletions builtin_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func (so *setObject) exportToArrayOrSlice(dst reflect.Value, typ reflect.Type, c
}

func (so *setObject) exportToMap(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
dst.Set(reflect.MakeMap(typ))
keyTyp := typ.Key()
elemTyp := typ.Elem()
iter := so.m.newIter()
Expand Down
40 changes: 40 additions & 0 deletions builtin_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,43 @@ func TestSetExportToArrayMismatchedLengths(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
}

func TestSetExportToNilMap(t *testing.T) {
vm := New()
var m map[int]interface{}
res, err := vm.RunString("new Set([1])")
if err != nil {
t.Fatal(err)
}
err = vm.ExportTo(res, &m)
if err != nil {
t.Fatal(err)
}
if len(m) != 1 {
t.Fatal(m)
}
if _, exists := m[1]; !exists {
t.Fatal(m)
}
}

func TestSetExportToNonNilMap(t *testing.T) {
vm := New()
m := map[int]interface{}{
2: true,
}
res, err := vm.RunString("new Set([1])")
if err != nil {
t.Fatal(err)
}
err = vm.ExportTo(res, &m)
if err != nil {
t.Fatal(err)
}
if len(m) != 1 {
t.Fatal(m)
}
if _, exists := m[1]; !exists {
t.Fatal(m)
}
}
4 changes: 1 addition & 3 deletions object.go
Original file line number Diff line number Diff line change
Expand Up @@ -987,9 +987,7 @@ func (o *baseObject) exportType() reflect.Type {
}

func genericExportToMap(o *Object, dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
if dst.IsNil() {
dst.Set(reflect.MakeMap(typ))
}
dst.Set(reflect.MakeMap(typ))
ctx.putTyped(o, typ, dst.Interface())
keyTyp := typ.Key()
elemTyp := typ.Elem()
Expand Down
21 changes: 21 additions & 0 deletions object_goreflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1244,3 +1244,24 @@ func TestGoReflectCopyOnWrite(t *testing.T) {
t.Fatal(err)
}
}

func TestReflectOverwriteReflectMap(t *testing.T) {
vm := New()
type S struct {
M map[int]interface{}
}
var s S
s.M = map[int]interface{}{
0: true,
}
vm.Set("s", &s)
_, err := vm.RunString(`
s.M = {1: false};
`)
if err != nil {
t.Fatal(err)
}
if _, exists := s.M[0]; exists {
t.Fatal(s)
}
}

0 comments on commit fdb999e

Please sign in to comment.