From 4d221ce468a1209ee9dd6cbece9d1273dad6a29b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Sun, 1 Aug 2021 11:50:12 +0200 Subject: [PATCH] Fail on invalid time zone Fixes #8832 --- hugolib/dates_test.go | 17 +++++++++++++++++ langs/config.go | 10 ++++++++++ langs/language.go | 37 ++++++++++++++++++++++--------------- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/hugolib/dates_test.go b/hugolib/dates_test.go index c9a33e0f8..dfcb681a3 100644 --- a/hugolib/dates_test.go +++ b/hugolib/dates_test.go @@ -15,6 +15,9 @@ package hugolib import ( "fmt" + + qt "github.com/frankban/quicktest" + "strings" "testing" ) @@ -186,3 +189,17 @@ ExpiryDate: 2099-07-13 15:28:01 +0000 UTC` b.AssertFileContent("public/nn/short-date-toml-qouted/index.html", expectShortDateNn) } + +// Issue 8832 +func TestTimeZoneInvalid(t *testing.T) { + b := newTestSitesBuilder(t) + + b.WithConfigFile("toml", ` + +timeZone = "America/LosAngeles" # Should be America/Los_Angeles +`) + + err := b.CreateSitesE() + b.Assert(err, qt.Not(qt.IsNil)) + b.Assert(err.Error(), qt.Contains, `failed to load config: invalid timeZone for language "en": unknown time zone America/LosAngeles`) +} diff --git a/langs/config.go b/langs/config.go index fe4ed9d14..f79b7dd0a 100644 --- a/langs/config.go +++ b/langs/config.go @@ -161,6 +161,12 @@ func LoadLanguageSettings(cfg config.Provider, oldLangs Languages) (c LanguagesC } } + for _, language := range c.Languages { + if language.initErr != nil { + return c, language.initErr + } + } + return c, nil } @@ -197,6 +203,10 @@ func toSortedLanguages(cfg config.Provider, l map[string]interface{}) (Languages for k, vv := range m { language.SetParam(k, vv) } + case "timezone": + if err := language.loadLocation(cast.ToString(v)); err != nil { + return nil, err + } } // Put all into the Params map diff --git a/langs/language.go b/langs/language.go index 758729c25..46f1be60e 100644 --- a/langs/language.go +++ b/langs/language.go @@ -19,6 +19,8 @@ import ( "sync" "time" + "github.com/pkg/errors" + translators "github.com/bep/gotranslators" "github.com/go-playground/locales" "github.com/gohugoio/hugo/common/maps" @@ -77,8 +79,10 @@ type Language struct { // TODO(bep) do the same for some of the others. translator locales.Translator - locationInit sync.Once - location *time.Location + location *time.Location + + // Error during initialization. Will fail the buld. + initErr error } func (l *Language) String() string { @@ -113,6 +117,11 @@ func NewLanguage(lang string, cfg config.Provider) *Language { params: params, translator: translator, } + + if err := l.loadLocation(cfg.GetString("timeZone")); err != nil { + l.initErr = err + } + return l } @@ -248,18 +257,6 @@ func (l *Language) IsSet(key string) bool { return l.Cfg.IsSet(key) } -func (l *Language) getLocation() *time.Location { - l.locationInit.Do(func() { - location, err := time.LoadLocation(l.GetString("timeZone")) - if err != nil { - location = time.UTC - } - l.location = location - }) - - return l.location -} - // Internal access to unexported Language fields. // This construct is to prevent them from leaking to the templates. @@ -268,5 +265,15 @@ func GetTranslator(l *Language) locales.Translator { } func GetLocation(l *Language) *time.Location { - return l.getLocation() + return l.location +} + +func (l *Language) loadLocation(tzStr string) error { + location, err := time.LoadLocation(tzStr) + if err != nil { + return errors.Wrapf(err, "invalid timeZone for language %q", l.Lang) + } + l.location = location + + return nil }