hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 4d221ce468a1209ee9dd6cbece9d1273dad6a29b
parent e3dc5240f01fd5ec67643e40f27c026d707da110
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Sun,  1 Aug 2021 11:50:12 +0200

Fail on invalid time zone

Fixes #8832

Diffstat:
Mhugolib/dates_test.go | 17+++++++++++++++++
Mlangs/config.go | 10++++++++++
Mlangs/language.go | 37++++++++++++++++++++++---------------
3 files changed, 49 insertions(+), 15 deletions(-)
diff --git 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
@@ -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
@@ -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
 }