From 8a7763b924262a8c1388406792490ff3c79a38e6 Mon Sep 17 00:00:00 2001 From: Daniel Borcherding Date: Fri, 17 Apr 2026 17:43:30 -0600 Subject: [PATCH] fix: nil map assignment panics on zero-value Viper struct --- viper.go | 12 ++++++++++++ viper_test.go | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/viper.go b/viper.go index 2d5158cbd..f092f68da 100644 --- a/viper.go +++ b/viper.go @@ -1538,6 +1538,12 @@ func SetDefault(key string, value any) { v.SetDefault(key, value) } // SetDefault is case-insensitive for a key. // Default only used when no value is provided by the user via flag, config or ENV. func (v *Viper) SetDefault(key string, value any) { + if v.defaults == nil { + v.defaults = make(map[string]any) + } + if v.keyDelim == "" { + v.keyDelim = "." + } // If alias passed in, then set the proper default key = v.realKey(strings.ToLower(key)) value = toCaseInsensitiveValue(value) @@ -1561,6 +1567,12 @@ func Set(key string, value any) { v.Set(key, value) } // Will be used instead of values obtained via // flags, config file, ENV, default, or key/value store. func (v *Viper) Set(key string, value any) { + if v.override == nil { + v.override = make(map[string]any) + } + if v.keyDelim == "" { + v.keyDelim = "." + } // If alias passed in, then set the proper override key = v.realKey(strings.ToLower(key)) value = toCaseInsensitiveValue(value) diff --git a/viper_test.go b/viper_test.go index 8b0232aee..40277837d 100644 --- a/viper_test.go +++ b/viper_test.go @@ -2718,3 +2718,19 @@ func skipWindows(t *testing.T) { t.Skip("Skip test on Windows") } } + +func TestZeroValueViperSetDefault(t *testing.T) { + v := &Viper{} + v.SetDefault("foo.bar", "baz") + if v.Get("foo.bar") != "baz" { + t.Fatalf("Expected baz, got %v", v.Get("foo.bar")) + } +} + +func TestZeroValueViperSet(t *testing.T) { + v := &Viper{} + v.Set("foo.bar", "baz") + if v.Get("foo.bar") != "baz" { + t.Fatalf("Expected baz, got %v", v.Get("foo.bar")) + } +}