From 5247643f02358b40d01385b0dbf743b659b0133f 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 | 11 +++++++++-- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/util.go b/util.go index ee7a86d..64e6575 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 i, val := range a { + a[i] = 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 c41a1e7..2a3dabc 100644 --- a/viper_test.go +++ b/viper_test.go @@ -2516,7 +2516,10 @@ func TestKeyDelimiter(t *testing.T) { } var yamlDeepNestedSlices = []byte(`TV: -- title: "The expanse" +- title: "The Expanse" + title_i18n: + USA: "The Expanse" + Japan: "エクスパンス -巨獣めざめる-" seasons: - first_released: "December 14, 2015" episodes: @@ -2546,11 +2549,15 @@ func TestSliceIndexAccess(t *testing.T) { err := v.unmarshalReader(r, v.config) require.NoError(t, err) - assert.Equal(t, "The expanse", v.GetString("tv.0.title")) + assert.Equal(t, "The Expanse", v.GetString("tv.0.title")) 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")) + // Test nested keys with capital letters + assert.Equal(t, "The Expanse", v.GetString("tv.0.title_i18n.USA")) + assert.Equal(t, "エクスパンス -巨獣めざめる-", v.GetString("tv.0.title_i18n.Japan")) + // Test for index out of bounds assert.Equal(t, "", v.GetString("tv.0.seasons.2.first_released"))