Skip to content

Commit 1f4a262

Browse files
committed
Zero reflect.Value between uses. Closes #145.
1 parent 9a0fd9e commit 1f4a262

File tree

4 files changed

+86
-3
lines changed

4 files changed

+86
-3
lines changed

decoder.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -596,18 +596,20 @@ func (d *decoder) decodeMap(
596596
mapType := result.Type()
597597
keyValue := reflect.New(mapType.Key()).Elem()
598598
elemType := mapType.Elem()
599-
elemKind := elemType.Kind()
600599
var elemValue reflect.Value
601600
for i := uint(0); i < size; i++ {
602601
var key []byte
603602
var err error
604603
key, offset, err = d.decodeKey(offset)
605-
606604
if err != nil {
607605
return 0, err
608606
}
609607

610-
if !elemValue.IsValid() || elemKind == reflect.Interface {
608+
if elemValue.IsValid() {
609+
// After 1.20 is the minimum supported version, this can just be
610+
// elemValue.SetZero()
611+
reflectSetZero(elemValue)
612+
} else {
611613
elemValue = reflect.New(elemType).Elem()
612614
}
613615

reader_test.go

+61
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,67 @@ func TestComplexStructWithNestingAndPointer(t *testing.T) {
454454
assert.NoError(t, reader.Close())
455455
}
456456

457+
// See GitHub #115.
458+
func TestNestedMapDecode(t *testing.T) {
459+
db, err := Open(testFile("GeoIP2-Country-Test.mmdb"))
460+
require.NoError(t, err)
461+
462+
var r map[string]map[string]any
463+
464+
require.NoError(t, db.Lookup(net.ParseIP("89.160.20.128"), &r))
465+
466+
assert.Equal(
467+
t,
468+
map[string]map[string]any{
469+
"continent": {
470+
"code": "EU",
471+
"geoname_id": uint64(6255148),
472+
"names": map[string]any{
473+
"de": "Europa",
474+
"en": "Europe",
475+
"es": "Europa",
476+
"fr": "Europe",
477+
"ja": "ヨーロッパ",
478+
"pt-BR": "Europa",
479+
"ru": "Европа",
480+
"zh-CN": "欧洲",
481+
},
482+
},
483+
"country": {
484+
"geoname_id": uint64(2661886),
485+
"is_in_european_union": true,
486+
"iso_code": "SE",
487+
"names": map[string]any{
488+
"de": "Schweden",
489+
"en": "Sweden",
490+
"es": "Suecia",
491+
"fr": "Suède",
492+
"ja": "スウェーデン王国",
493+
"pt-BR": "Suécia",
494+
"ru": "Швеция",
495+
"zh-CN": "瑞典",
496+
},
497+
},
498+
"registered_country": {
499+
"geoname_id": uint64(2921044),
500+
"is_in_european_union": true,
501+
"iso_code": "DE",
502+
"names": map[string]any{
503+
"de": "Deutschland",
504+
"en": "Germany",
505+
"es": "Alemania",
506+
"fr": "Allemagne",
507+
"ja": "ドイツ連邦共和国",
508+
"pt-BR": "Alemanha",
509+
"ru": "Германия",
510+
"zh-CN": "德国",
511+
},
512+
},
513+
},
514+
r,
515+
)
516+
}
517+
457518
func TestNestedOffsetDecode(t *testing.T) {
458519
db, err := Open(testFile("GeoIP2-City-Test.mmdb"))
459520
require.NoError(t, err)

set_zero_120.go

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//go:build go1.20
2+
// +build go1.20
3+
4+
package maxminddb
5+
6+
import "reflect"
7+
8+
func reflectSetZero(v reflect.Value) {
9+
v.SetZero()
10+
}

set_zero_pre120.go

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//go:build !go1.20
2+
// +build !go1.20
3+
4+
package maxminddb
5+
6+
import "reflect"
7+
8+
func reflectSetZero(v reflect.Value) {
9+
v.Set(reflect.Zero(v.Type()))
10+
}

0 commit comments

Comments
 (0)