Skip to content

Commit

Permalink
check for nil pointers before calling IsZero.
Browse files Browse the repository at this point in the history
This avoids panics when a nil pointer to a type that implements zeroable interface is passed to IsZero
  • Loading branch information
mszczygiel committed Mar 23, 2023
1 parent 0579829 commit 097d71b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
11 changes: 10 additions & 1 deletion util.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,12 +341,21 @@ type zeroable interface {
// IsZero returns true when the value passed into the function is a zero value.
// This allows for safer checking of interface values.
func IsZero(data interface{}) bool {
v := reflect.ValueOf(data)
// check for nil data
switch v.Kind() {
case reflect.Interface, reflect.Ptr:
if v.IsNil() {
return true
}
}

// check for things that have an IsZero method instead
if vv, ok := data.(zeroable); ok {
return vv.IsZero()
}

// continue with slightly more complex reflection
v := reflect.ValueOf(data)
switch v.Kind() {
case reflect.String:
return v.Len() == 0
Expand Down
18 changes: 18 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,3 +490,21 @@ func TestToGoNameUnicode(t *testing.T) {
assert.Equal(t, sample.out, ToGoName(sample.str))
}
}

type dummyZeroable struct {
zero bool
}

func (d dummyZeroable) IsZero() bool {
return d.zero
}
func TestZeroableNilIsZero(t *testing.T) {
var d *dummyZeroable

assert.True(t, IsZero(d))
}

func TestZeroableInterfaceIsRespected(t *testing.T) {
assert.False(t, IsZero(dummyZeroable{false}))
assert.True(t, IsZero(dummyZeroable{true}))
}

0 comments on commit 097d71b

Please sign in to comment.