From 140662f1ec94b3f5e0666ae50c9a164e5ed3a0e2 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sun, 7 Jun 2020 17:31:16 -0400 Subject: [PATCH] Verify that all settings have correct type This prevents crashes that occur when the user has put the wrong type for a setting manually in the settings.json file. --- cmd/micro/micro.go | 5 ++++- internal/action/command.go | 5 ++++- internal/config/settings.go | 28 +++++++++++++++++++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index 69962b62..275ff503 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -243,7 +243,10 @@ func main() { if err != nil { screen.TermMessage(err) } - config.InitGlobalSettings() + err = config.InitGlobalSettings() + if err != nil { + screen.TermMessage(err) + } // flag options for k, v := range optionFlags { diff --git a/internal/action/command.go b/internal/action/command.go index b85117b7..8034f291 100644 --- a/internal/action/command.go +++ b/internal/action/command.go @@ -339,7 +339,10 @@ func ReloadConfig() { if err != nil { screen.TermMessage(err) } - config.InitGlobalSettings() + err = config.InitGlobalSettings() + if err != nil { + screen.TermMessage(err) + } InitBindings() InitCommands() diff --git a/internal/config/settings.go b/internal/config/settings.go index 5c75f18d..a306389c 100644 --- a/internal/config/settings.go +++ b/internal/config/settings.go @@ -3,6 +3,7 @@ package config import ( "encoding/json" "errors" + "fmt" "io/ioutil" "os" "path/filepath" @@ -75,16 +76,33 @@ func ReadSettings() error { return nil } +func verifySetting(option string, value reflect.Type, def reflect.Type) bool { + var interfaceArr []interface{} + switch option { + case "pluginrepos", "pluginchannels": + return value.AssignableTo(reflect.TypeOf(interfaceArr)) + default: + return def.AssignableTo(value) + } +} + // InitGlobalSettings initializes the options map and sets all options to their default values // Must be called after ReadSettings -func InitGlobalSettings() { +func InitGlobalSettings() error { + var err error GlobalSettings = DefaultGlobalSettings() for k, v := range parsedSettings { if !strings.HasPrefix(reflect.TypeOf(v).String(), "map") { + if _, ok := GlobalSettings[k]; ok && !verifySetting(k, reflect.TypeOf(v), reflect.TypeOf(GlobalSettings[k])) { + err = errors.New(fmt.Sprintf("Global Error: setting '%s' has incorrect type (%s), using default value: %v (%s)", k, reflect.TypeOf(v), GlobalSettings[k], reflect.TypeOf(GlobalSettings[k]))) + continue + } + GlobalSettings[k] = v } } + return err } // InitLocalSettings scans the json in settings.json and sets the options locally based @@ -97,6 +115,10 @@ func InitLocalSettings(settings map[string]interface{}, path string) error { if strings.HasPrefix(k, "ft:") { if settings["filetype"].(string) == k[3:] { for k1, v1 := range v.(map[string]interface{}) { + if _, ok := settings[k1]; ok && !verifySetting(k1, reflect.TypeOf(v1), reflect.TypeOf(settings[k1])) { + parseError = errors.New(fmt.Sprintf("Error: setting '%s' has incorrect type (%s), using default value: %v (%s)", k, reflect.TypeOf(v1), settings[k1], reflect.TypeOf(settings[k1]))) + continue + } settings[k1] = v1 } } @@ -109,6 +131,10 @@ func InitLocalSettings(settings map[string]interface{}, path string) error { if g.MatchString(path) { for k1, v1 := range v.(map[string]interface{}) { + if _, ok := settings[k1]; ok && !verifySetting(k1, reflect.TypeOf(v1), reflect.TypeOf(settings[k1])) { + parseError = errors.New(fmt.Sprintf("Error: setting '%s' has incorrect type (%s), using default value: %v (%s)", k, reflect.TypeOf(v1), settings[k1], reflect.TypeOf(settings[k1]))) + continue + } settings[k1] = v1 } }