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.
This commit is contained in:
Zachary Yedidia 2020-06-07 17:31:16 -04:00
parent 44c1929f9d
commit 140662f1ec
3 changed files with 35 additions and 3 deletions

View file

@ -243,7 +243,10 @@ func main() {
if err != nil { if err != nil {
screen.TermMessage(err) screen.TermMessage(err)
} }
config.InitGlobalSettings() err = config.InitGlobalSettings()
if err != nil {
screen.TermMessage(err)
}
// flag options // flag options
for k, v := range optionFlags { for k, v := range optionFlags {

View file

@ -339,7 +339,10 @@ func ReloadConfig() {
if err != nil { if err != nil {
screen.TermMessage(err) screen.TermMessage(err)
} }
config.InitGlobalSettings() err = config.InitGlobalSettings()
if err != nil {
screen.TermMessage(err)
}
InitBindings() InitBindings()
InitCommands() InitCommands()

View file

@ -3,6 +3,7 @@ package config
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -75,16 +76,33 @@ func ReadSettings() error {
return nil 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 // InitGlobalSettings initializes the options map and sets all options to their default values
// Must be called after ReadSettings // Must be called after ReadSettings
func InitGlobalSettings() { func InitGlobalSettings() error {
var err error
GlobalSettings = DefaultGlobalSettings() GlobalSettings = DefaultGlobalSettings()
for k, v := range parsedSettings { for k, v := range parsedSettings {
if !strings.HasPrefix(reflect.TypeOf(v).String(), "map") { 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 GlobalSettings[k] = v
} }
} }
return err
} }
// InitLocalSettings scans the json in settings.json and sets the options locally based // 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 strings.HasPrefix(k, "ft:") {
if settings["filetype"].(string) == k[3:] { if settings["filetype"].(string) == k[3:] {
for k1, v1 := range v.(map[string]interface{}) { 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 settings[k1] = v1
} }
} }
@ -109,6 +131,10 @@ func InitLocalSettings(settings map[string]interface{}, path string) error {
if g.MatchString(path) { if g.MatchString(path) {
for k1, v1 := range v.(map[string]interface{}) { 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 settings[k1] = v1
} }
} }