Skip to content

Commit

Permalink
Zero reflect.Value between uses. Closes #145.
Browse files Browse the repository at this point in the history
  • Loading branch information
oschwald committed Aug 1, 2023
1 parent 9a0fd9e commit 1f4a262
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 3 deletions.
8 changes: 5 additions & 3 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,18 +596,20 @@ func (d *decoder) decodeMap(
mapType := result.Type()
keyValue := reflect.New(mapType.Key()).Elem()
elemType := mapType.Elem()
elemKind := elemType.Kind()
var elemValue reflect.Value
for i := uint(0); i < size; i++ {
var key []byte
var err error
key, offset, err = d.decodeKey(offset)

if err != nil {
return 0, err
}

if !elemValue.IsValid() || elemKind == reflect.Interface {
if elemValue.IsValid() {
// After 1.20 is the minimum supported version, this can just be
// elemValue.SetZero()
reflectSetZero(elemValue)
} else {
elemValue = reflect.New(elemType).Elem()
}

Expand Down
61 changes: 61 additions & 0 deletions reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,67 @@ func TestComplexStructWithNestingAndPointer(t *testing.T) {
assert.NoError(t, reader.Close())
}

// See GitHub #115.
func TestNestedMapDecode(t *testing.T) {
db, err := Open(testFile("GeoIP2-Country-Test.mmdb"))
require.NoError(t, err)

var r map[string]map[string]any

require.NoError(t, db.Lookup(net.ParseIP("89.160.20.128"), &r))

assert.Equal(
t,
map[string]map[string]any{
"continent": {
"code": "EU",
"geoname_id": uint64(6255148),
"names": map[string]any{
"de": "Europa",
"en": "Europe",
"es": "Europa",
"fr": "Europe",
"ja": "ヨーロッパ",
"pt-BR": "Europa",
"ru": "Европа",
"zh-CN": "欧洲",
},
},
"country": {
"geoname_id": uint64(2661886),
"is_in_european_union": true,
"iso_code": "SE",
"names": map[string]any{
"de": "Schweden",
"en": "Sweden",
"es": "Suecia",
"fr": "Suède",
"ja": "スウェーデン王国",
"pt-BR": "Suécia",
"ru": "Швеция",
"zh-CN": "瑞典",
},
},
"registered_country": {
"geoname_id": uint64(2921044),
"is_in_european_union": true,
"iso_code": "DE",
"names": map[string]any{
"de": "Deutschland",
"en": "Germany",
"es": "Alemania",
"fr": "Allemagne",
"ja": "ドイツ連邦共和国",
"pt-BR": "Alemanha",
"ru": "Германия",
"zh-CN": "德国",
},
},
},
r,
)
}

func TestNestedOffsetDecode(t *testing.T) {
db, err := Open(testFile("GeoIP2-City-Test.mmdb"))
require.NoError(t, err)
Expand Down
10 changes: 10 additions & 0 deletions set_zero_120.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//go:build go1.20
// +build go1.20

package maxminddb

import "reflect"

func reflectSetZero(v reflect.Value) {
v.SetZero()
}
10 changes: 10 additions & 0 deletions set_zero_pre120.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//go:build !go1.20
// +build !go1.20

package maxminddb

import "reflect"

func reflectSetZero(v reflect.Value) {
v.Set(reflect.Zero(v.Type()))
}

0 comments on commit 1f4a262

Please sign in to comment.