From 4652c9330d1e5ce33caaf8bd9ad86a4a9932611b Mon Sep 17 00:00:00 2001 From: Andrew Richardson Date: Thu, 23 Jun 2022 17:34:55 -0400 Subject: [PATCH] Recurse into arrays when converting keys to lowercase Fixes #1386 Signed-off-by: Andrew Richardson --- util.go | 33 +++++++++++++++++++++++---------- viper_test.go | 2 ++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/util.go b/util.go index ee7a86d9df..873efac34e 100644 --- a/util.go +++ b/util.go @@ -64,18 +64,25 @@ func copyAndInsensitiviseMap(m map[string]interface{}) map[string]interface{} { return nm } +func insensitiviseVal(val interface{}) interface{} { + switch val.(type) { + case map[interface{}]interface{}: + // nested map: cast and recursively insensitivise + val = cast.ToStringMap(val) + insensitiviseMap(val.(map[string]interface{})) + case map[string]interface{}: + // nested map: recursively insensitivise + insensitiviseMap(val.(map[string]interface{})) + case []interface{}: + // nested array: recursively insensitivise + insensitiveArray(val.([]interface{})) + } + return val +} + func insensitiviseMap(m map[string]interface{}) { for key, val := range m { - switch val.(type) { - case map[interface{}]interface{}: - // nested map: cast and recursively insensitivise - val = cast.ToStringMap(val) - insensitiviseMap(val.(map[string]interface{})) - case map[string]interface{}: - // nested map: recursively insensitivise - insensitiviseMap(val.(map[string]interface{})) - } - + val = insensitiviseVal(val) lower := strings.ToLower(key) if key != lower { // remove old key (not lower-cased) @@ -86,6 +93,12 @@ func insensitiviseMap(m map[string]interface{}) { } } +func insensitiveArray(a []interface{}) { + for _, val := range a { + insensitiviseVal(val) + } +} + func absPathify(logger Logger, inPath string) string { logger.Info("trying to resolve absolute path", "path", inPath) diff --git a/viper_test.go b/viper_test.go index c41a1e7499..536a53de50 100644 --- a/viper_test.go +++ b/viper_test.go @@ -2517,6 +2517,7 @@ func TestKeyDelimiter(t *testing.T) { var yamlDeepNestedSlices = []byte(`TV: - title: "The expanse" + originalNetwork: "syfy" seasons: - first_released: "December 14, 2015" episodes: @@ -2547,6 +2548,7 @@ func TestSliceIndexAccess(t *testing.T) { require.NoError(t, err) assert.Equal(t, "The expanse", v.GetString("tv.0.title")) + assert.Equal(t, "syfy", v.GetString("tv.0.originalNetwork")) assert.Equal(t, "February 1, 2017", v.GetString("tv.0.seasons.1.first_released")) assert.Equal(t, "Static", v.GetString("tv.0.seasons.1.episodes.2.title")) assert.Equal(t, "December 15, 2015", v.GetString("tv.0.seasons.0.episodes.1.air_date"))