From c6558fbcb9bb30b7a2ec2b28a8d1e94b5afa2c5f Mon Sep 17 00:00:00 2001 From: Emmanuel T Odeke Date: Tue, 20 Oct 2020 05:41:44 -0700 Subject: [PATCH] server: catch and return unhandled errors in interceptConfigs (#7587) Catches and returns unhandled errors after stat-ing for the configFile, instead of assuming that we'd only encounter a non-existent error. Added a regression test to lock-in checks for unhandled errors like Permission errors, which is representative of all the errors that haven't been accounted for. Fixes #7578 Co-authored-by: Aleksandr Bezobchuk Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- server/util.go | 9 +++++++-- server/util_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/server/util.go b/server/util.go index 8407f9b492..b95f8ad505 100644 --- a/server/util.go +++ b/server/util.go @@ -146,7 +146,8 @@ func interceptConfigs(rootViper *viper.Viper) (*tmcfg.Config, error) { conf := tmcfg.DefaultConfig() - if _, err := os.Stat(configFile); os.IsNotExist(err) { + switch _, err := os.Stat(configFile); { + case os.IsNotExist(err): tmcfg.EnsureRoot(rootDir) if err = conf.ValidateBasic(); err != nil { @@ -158,7 +159,11 @@ func interceptConfigs(rootViper *viper.Viper) (*tmcfg.Config, error) { conf.P2P.SendRate = 5120000 conf.Consensus.TimeoutCommit = 5 * time.Second tmcfg.WriteConfigFile(configFile, conf) - } else { + + case err != nil: + return nil, err + + default: rootViper.SetConfigType("toml") rootViper.SetConfigName("config") rootViper.AddConfigPath(configPath) diff --git a/server/util_test.go b/server/util_test.go index 7cc10b3542..582fb4c089 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "path" + "path/filepath" "strings" "testing" @@ -444,3 +445,26 @@ func TestInterceptConfigsPreRunHandlerPrecedenceConfigDefault(t *testing.T) { t.Error("RPCListenAddress is not using default") } } + +// Ensure that if interceptConfigs encounters any error other than non-existen errors +// that we correctly return the offending error, for example a permission error. +// See https://github.com/cosmos/cosmos-sdk/issues/7578 +func TestInterceptConfigsWithBadPermissions(t *testing.T) { + tempDir := t.TempDir() + subDir := filepath.Join(tempDir, "nonPerms") + if err := os.Mkdir(subDir, 0600); err != nil { + t.Fatalf("Failed to create sub directory: %v", err) + } + cmd := StartCmd(nil, "/foobar") + if err := cmd.Flags().Set(flags.FlagHome, subDir); err != nil { + t.Fatalf("Could not set home flag [%T] %v", err, err) + } + + cmd.PreRunE = preRunETestImpl + + serverCtx := &Context{} + ctx := context.WithValue(context.Background(), ServerContextKey, serverCtx) + if err := cmd.ExecuteContext(ctx); !os.IsPermission(err) { + t.Fatalf("Failed to catch permissions error, got: [%T] %v", err, err) + } +}