Skip to content

Commit

Permalink
Fix panic with embedded struct. GitHub #28
Browse files Browse the repository at this point in the history
  • Loading branch information
oschwald committed Sep 19, 2016
1 parent 481716c commit 2af0544
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
27 changes: 19 additions & 8 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,19 +139,30 @@ func (d *decoder) unmarshalBool(size uint, offset uint, result reflect.Value) (u
return newOffset, newUnmarshalTypeError(value, result.Type())
}

// follow pointers and create values as necessary
// indirect follows pointers and create values as necessary. This is
// heavily based on encoding/json as my original version had a subtle
// bug. This method should be considered to be licensed under
// https://golang.org/LICENSE
func (d *decoder) indirect(result reflect.Value) reflect.Value {
for {
if result.Kind() == reflect.Ptr {
if result.IsNil() {
result.Set(reflect.New(result.Type().Elem()))
// Load value from interface, but only if the result will be
// usefully addressable.
if result.Kind() == reflect.Interface && !result.IsNil() {
e := result.Elem()
if e.Kind() == reflect.Ptr && !e.IsNil() {
result = e
continue
}
result = result.Elem()
} else if result.Kind() == reflect.Interface && !result.IsNil() {
result = result.Elem()
} else {
}

if result.Kind() != reflect.Ptr {
break
}

if result.IsNil() {
result.Set(reflect.New(result.Type().Elem()))
}
result = result.Elem()
}
return result
}
Expand Down
18 changes: 18 additions & 0 deletions reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,24 @@ func TestNonEmptyNilInterface(t *testing.T) {
assert.Equal(t, err.Error(), "maxminddb: cannot unmarshal map into type maxminddb.TestInterface")
}

type CityTraits struct {
AutonomousSystemNumber uint `json:"autonomous_system_number,omitempty" maxminddb:"autonomous_system_number"`
}

type City struct {
Traits CityTraits `maxminddb:"traits"`
}

func TestEmbeddedStructAsInterface(t *testing.T) {
var city City
var result interface{} = city.Traits

db, err := Open("test-data/test-data/GeoIP2-ISP-Test.mmdb")
require.Nil(t, err)

assert.Nil(t, db.Lookup(net.ParseIP("1.128.0.0"), &result))
}

type BoolInterface interface {
true() bool
}
Expand Down

0 comments on commit 2af0544

Please sign in to comment.