From 321039338cea661ec846d2855beb42c6728c27c4 Mon Sep 17 00:00:00 2001 From: team-humaki Date: Fri, 11 Sep 2026 10:52:04 -0700 Subject: [PATCH] MapTo: return error for nil struct pointer instead of panic Calling MapTo(&cfg) when cfg is a nil *T used to panic in mapToField. Return a clear error instead (#369). Fixes #369 --- struct.go | 8 ++++++++ struct_test.go | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/struct.go b/struct.go index 819a6e5..d70e11e 100644 --- a/struct.go +++ b/struct.go @@ -381,6 +381,9 @@ func (s *Section) mapToSlice(secName string, val reflect.Value, isStrict bool) ( func (s *Section) mapTo(v interface{}, isStrict bool) error { typ := reflect.TypeOf(v) val := reflect.ValueOf(v) + if typ == nil || !val.IsValid() { + return errors.New("nil pointer to a struct") + } if typ.Kind() == reflect.Pointer { typ = typ.Elem() val = val.Elem() @@ -388,6 +391,11 @@ func (s *Section) mapTo(v interface{}, isStrict bool) error { return errors.New("not a pointer to a struct") } + // MapTo(&cfg) where cfg is a nil *T used to panic in mapToField (#369). + if !val.IsValid() || (val.Kind() == reflect.Pointer && val.IsNil()) { + return errors.New("nil pointer to a struct") + } + if typ.Kind() == reflect.Slice { newField, err := s.mapToSlice(s.name, val, isStrict) if err != nil { diff --git a/struct_test.go b/struct_test.go index ad6ad04..997f8d1 100644 --- a/struct_test.go +++ b/struct_test.go @@ -910,3 +910,17 @@ Title = Consultant Engineer ) }) } + +func TestMapToNilStructPointer(t *testing.T) { + t.Run("nil pointer to struct", func(t *testing.T) { + type Config struct { + User string `ini:"user"` + Pass string `ini:"pass"` + } + var cfg *Config + f, err := Load([]byte("user = alice\npass = secret\n")) + require.NoError(t, err) + err = f.MapTo(&cfg) + assert.EqualError(t, err, "nil pointer to a struct") + }) +}