]> git.lizzy.rs Git - micro.git/commitdiff
Verify that all settings have correct type
authorZachary Yedidia <zyedidia@gmail.com>
Sun, 7 Jun 2020 21:31:16 +0000 (17:31 -0400)
committerZachary Yedidia <zyedidia@gmail.com>
Sun, 7 Jun 2020 21:31:16 +0000 (17:31 -0400)
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
internal/action/command.go
internal/config/settings.go

index 69962b628f05de085902fd066773fd818850b4c5..275ff5032a111fd4c61d25589697a1475ced7287 100644 (file)
@@ -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 {
index b85117b79f5d8677714b0ac72cbf5e623f587008..8034f291a82a7895b254453f8659784ec96c0641 100644 (file)
@@ -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()
 
index 5c75f18d4bc40b9058018ae92e300f1e96c64b64..a306389cf98b0ab8121c0fa417b71a578c2ec3ed 100644 (file)
@@ -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
                                        }
                                }