From b3f48212f16f37db9817e1463909706687a8c5d3 Mon Sep 17 00:00:00 2001 From: John Guo Date: Wed, 20 Mar 2024 19:52:12 +0800 Subject: [PATCH] fix: #3362 `IsEmpty` panics when some interface implement panics with nil receiver (#3367) --- internal/empty/empty.go | 14 +++++++++--- internal/empty/empty_z_unit_test.go | 35 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/internal/empty/empty.go b/internal/empty/empty.go index 07fee1e2415..5ca3d3b7edd 100644 --- a/internal/empty/empty.go +++ b/internal/empty/empty.go @@ -97,6 +97,11 @@ func IsEmpty(value interface{}, traceSource ...bool) bool { if v, ok := value.(reflect.Value); ok { rv = v } else { + rv = reflect.ValueOf(value) + if IsNil(rv) { + return true + } + // ========================= // Common interfaces checks. // ========================= @@ -124,8 +129,6 @@ func IsEmpty(value interface{}, traceSource ...bool) bool { } return len(f.MapStrAny()) == 0 } - - rv = reflect.ValueOf(value) } switch rv.Kind() { @@ -188,9 +191,11 @@ func IsEmpty(value interface{}, traceSource ...bool) bool { case reflect.Invalid: return true + + default: + return false } } - return false } // IsNil checks whether given `value` is nil, especially for interface{} type value. @@ -230,6 +235,9 @@ func IsNil(value interface{}, traceSource ...bool) bool { } else { return !rv.IsValid() || rv.IsNil() } + + default: + return false } return false } diff --git a/internal/empty/empty_z_unit_test.go b/internal/empty/empty_z_unit_test.go index 6b9efed1e58..6acb52638f9 100644 --- a/internal/empty/empty_z_unit_test.go +++ b/internal/empty/empty_z_unit_test.go @@ -8,7 +8,9 @@ package empty_test import ( "testing" + "time" + "github.com/gogf/gf/v2/container/gvar" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/internal/empty" "github.com/gogf/gf/v2/test/gtest" @@ -128,3 +130,36 @@ func TestIsNil(t *testing.T) { t.Assert(empty.IsNil(&i, true), true) }) } + +type Issue3362St struct { + time.Time +} + +func Test_Issue3362(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + type A struct { + Issue3362 *Issue3362St `json:"issue,omitempty"` + } + m := gvar.New( + &A{}, + ).Map( + gvar.MapOption{ + OmitEmpty: true, + }, + ) + t.Assert(m, nil) + }) + gtest.C(t, func(t *gtest.T) { + var i int + t.Assert(empty.IsNil(i), false) + }) + gtest.C(t, func(t *gtest.T) { + var i *int + t.Assert(empty.IsNil(i), true) + }) + gtest.C(t, func(t *gtest.T) { + var i *int + t.Assert(empty.IsNil(&i), false) + t.Assert(empty.IsNil(&i, true), true) + }) +}