report an error if configs mix up lower case and upper case keys

This commit is contained in:
cmohrb 2021-01-20 14:33:23 +01:00 committed by Christian Mohrbacher
parent 4f738d6f3f
commit 4e1c7f43f5
2 changed files with 51 additions and 13 deletions

25
util.go
View file

@ -66,21 +66,30 @@ func copyAndInsensitiviseMap(m map[string]interface{}) map[string]interface{} {
return nm return nm
} }
func insensitiviseMap(m map[string]interface{}) { func insensitiviseMap(m map[string]interface{}) error {
for key, val := range m { for key, val := range m {
switch val.(type) { switch val.(type) {
case map[interface{}]interface{}: case map[interface{}]interface{}:
// nested map: cast and recursively insensitivise // nested map: cast and recursively insensitivise
val = cast.ToStringMap(val) val = cast.ToStringMap(val)
insensitiviseMap(val.(map[string]interface{})) err := insensitiviseMap(val.(map[string]interface{}))
if err != nil {
return err
}
case map[string]interface{}: case map[string]interface{}:
// nested map: recursively insensitivise // nested map: recursively insensitivise
insensitiviseMap(val.(map[string]interface{})) err := insensitiviseMap(val.(map[string]interface{}))
if err != nil {
return err
}
case []interface{}: case []interface{}:
for _, x := range val.([]interface{}) { for _, x := range val.([]interface{}) {
y, ok := x.(map[string]interface{}) y, ok := x.(map[string]interface{})
if ok { if ok {
insensitiviseMap(y) err := insensitiviseMap(y)
if err != nil {
return err
}
} }
} }
} }
@ -90,9 +99,17 @@ func insensitiviseMap(m map[string]interface{}) {
// remove old key (not lower-cased) // remove old key (not lower-cased)
delete(m, key) delete(m, key)
} }
_, exists := m[lower]
if key != lower && exists {
return fmt.Errorf("Name clash bewteen keys: %s and %s", key, lower)
}
// update map // update map
m[lower] = val m[lower] = val
} }
return nil
} }
func absPathify(inPath string) string { func absPathify(inPath string) string {

View file

@ -753,7 +753,10 @@ func (v *Viper) UnmarshalKey(key string, rawVal interface{}) error {
return err return err
} }
v.insensitiviseMaps() err = v.insensitiviseMaps()
if err != nil {
return err
}
return nil return nil
} }
@ -768,7 +771,10 @@ func (v *Viper) Unmarshal(rawVal interface{}) error {
return err return err
} }
v.insensitiviseMaps() err = v.insensitiviseMaps()
if err != nil {
return err
}
return nil return nil
} }
@ -808,7 +814,10 @@ func (v *Viper) UnmarshalExact(rawVal interface{}) error {
return err return err
} }
v.insensitiviseMaps() err = v.insensitiviseMaps()
if err != nil {
return err
}
return nil return nil
} }
@ -1332,7 +1341,10 @@ func (v *Viper) unmarshalReader(in io.Reader, c map[string]interface{}) error {
} }
} }
insensitiviseMap(c) err := insensitiviseMap(c)
if err != nil {
return err
}
return nil return nil
} }
@ -1514,11 +1526,20 @@ func (v *Viper) WatchRemoteConfigOnChannel() error {
return v.watchKeyValueConfigOnChannel() return v.watchKeyValueConfigOnChannel()
} }
func (v *Viper) insensitiviseMaps() { func (v *Viper) insensitiviseMaps() error {
insensitiviseMap(v.config) if err := insensitiviseMap(v.config); err != nil {
insensitiviseMap(v.defaults) return err
insensitiviseMap(v.override) }
insensitiviseMap(v.kvstore) if err := insensitiviseMap(v.defaults); err != nil {
return err
}
if err := insensitiviseMap(v.override); err != nil {
return err
}
if err := insensitiviseMap(v.kvstore); err != nil {
return err
}
return nil
} }
// Retrieve the first found remote configuration. // Retrieve the first found remote configuration.