config: Fix handling of invalid OS env config overrides
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 29 Jun 2021 07:38:05 +0000 (09:38 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 29 Jun 2021 07:38:05 +0000 (09:38 +0200)
Fixes #8709

config/defaultConfigProvider.go
hugolib/config_test.go

index 80353664e413f3c93bf37dc3829bee559351288c..9f1c44ee12a0b51acb16863bf836f9c163a38cba 100644 (file)
@@ -169,6 +169,9 @@ func (c *defaultConfigProvider) Set(k string, v interface{}) {
        }
 
        key, m := c.getNestedKeyAndMap(k, true)
+       if m == nil {
+               return
+       }
 
        if existing, found := m[key]; found {
                if p1, ok := existing.(maps.Params); ok {
@@ -289,6 +292,9 @@ func (c *defaultConfigProvider) Merge(k string, v interface{}) {
        }
 
        key, m := c.getNestedKeyAndMap(k, true)
+       if m == nil {
+               return
+       }
 
        if existing, found := m[key]; found {
                if p1, ok := existing.(maps.Params); ok {
@@ -422,7 +428,12 @@ func (c *defaultConfigProvider) getNestedKeyAndMap(key string, create bool) (str
                                return "", nil
                        }
                }
-               current = next.(maps.Params)
+               var ok bool
+               current, ok = next.(maps.Params)
+               if !ok {
+                       // E.g. a string, not a map that we can store values in.
+                       return "", nil
+               }
        }
        return parts[len(parts)-1], current
 }
index c5e77c94668a3adf99c7f63e6f780912ab62ebab..810ab18f5b9eb08e9d04329f7452b2fc72b6d2f0 100644 (file)
@@ -576,9 +576,10 @@ anchor = "smart"
 quality = 75 
 `
 
-       b := newTestSitesBuilder(t).WithConfigFile("toml", baseConfig)
+       newB := func(t testing.TB) *sitesBuilder {
+               b := newTestSitesBuilder(t).WithConfigFile("toml", baseConfig)
 
-       b.WithSourceFile("themes/mytheme/config.toml", `
+               b.WithSourceFile("themes/mytheme/config.toml", `
 
 [outputFormats]
 [outputFormats.oftheme]
@@ -595,64 +596,90 @@ theme_param="themevalue2"
 
 `)
 
-       b.WithEnviron(
-               "HUGO_ENVIRONMENT", "test",
-               "HUGO_NEW", "new", // key not in config.toml
-               "HUGO_ENABLEGITINFO", "false",
-               "HUGO_IMAGING_ANCHOR", "top",
-               "HUGO_IMAGING_RESAMPLEFILTER", "CatmullRom",
-               "HUGO_STRINGSLICE", `["c", "d"]`,
-               "HUGO_INTSLICE", `[5, 8, 9]`,
-               "HUGO_FLOATSLICE", `[5.32]`,
-               // Issue #7829
-               "HUGOxPARAMSxAPI_CONFIGxAPI_KEY", "new_key",
-               // Delimiters are case sensitive.
-               "HUGOxPARAMSxAPI_CONFIGXANOTHER_KEY", "another_key",
-               // Issue #8346
-               "HUGOxPARAMSxMYTHEME_SECTIONxTHEME_PARAM", "themevalue_changed",
-               "HUGOxPARAMSxMYTHEME_SECTION2xTHEME_PARAM", "themevalue2_changed",
-               "HUGO_PARAMS_EMPTY", ``,
-               "HUGO_PARAMS_HTML", `<a target="_blank" />`,
-               // Issue #8618
-               "HUGO_SERVICES_GOOGLEANALYTICS_ID", `gaid`,
-               "HUGO_PARAMS_A_B_C", "abc",
-       )
+               return b
+       }
 
-       b.Build(BuildCfg{})
+       c.Run("Variations", func(c *qt.C) {
+
+               b := newB(c)
+
+               b.WithEnviron(
+                       "HUGO_ENVIRONMENT", "test",
+                       "HUGO_NEW", "new", // key not in config.toml
+                       "HUGO_ENABLEGITINFO", "false",
+                       "HUGO_IMAGING_ANCHOR", "top",
+                       "HUGO_IMAGING_RESAMPLEFILTER", "CatmullRom",
+                       "HUGO_STRINGSLICE", `["c", "d"]`,
+                       "HUGO_INTSLICE", `[5, 8, 9]`,
+                       "HUGO_FLOATSLICE", `[5.32]`,
+                       // Issue #7829
+                       "HUGOxPARAMSxAPI_CONFIGxAPI_KEY", "new_key",
+                       // Delimiters are case sensitive.
+                       "HUGOxPARAMSxAPI_CONFIGXANOTHER_KEY", "another_key",
+                       // Issue #8346
+                       "HUGOxPARAMSxMYTHEME_SECTIONxTHEME_PARAM", "themevalue_changed",
+                       "HUGOxPARAMSxMYTHEME_SECTION2xTHEME_PARAM", "themevalue2_changed",
+                       "HUGO_PARAMS_EMPTY", ``,
+                       "HUGO_PARAMS_HTML", `<a target="_blank" />`,
+                       // Issue #8618
+                       "HUGO_SERVICES_GOOGLEANALYTICS_ID", `gaid`,
+                       "HUGO_PARAMS_A_B_C", "abc",
+               )
+
+               b.Build(BuildCfg{})
+
+               cfg := b.H.Cfg
+               s := b.H.Sites[0]
+               scfg := s.siteConfigConfig.Services
+
+               c.Assert(cfg.Get("environment"), qt.Equals, "test")
+               c.Assert(cfg.GetBool("enablegitinfo"), qt.Equals, false)
+               c.Assert(cfg.Get("new"), qt.Equals, "new")
+               c.Assert(cfg.Get("imaging.anchor"), qt.Equals, "top")
+               c.Assert(cfg.Get("imaging.quality"), qt.Equals, int64(75))
+               c.Assert(cfg.Get("imaging.resamplefilter"), qt.Equals, "CatmullRom")
+               c.Assert(cfg.Get("stringSlice"), qt.DeepEquals, []interface{}{"c", "d"})
+               c.Assert(cfg.Get("floatSlice"), qt.DeepEquals, []interface{}{5.32})
+               c.Assert(cfg.Get("intSlice"), qt.DeepEquals, []interface{}{5, 8, 9})
+               c.Assert(cfg.Get("params.api_config.api_key"), qt.Equals, "new_key")
+               c.Assert(cfg.Get("params.api_config.another_key"), qt.Equals, "default another_key")
+               c.Assert(cfg.Get("params.mytheme_section.theme_param"), qt.Equals, "themevalue_changed")
+               c.Assert(cfg.Get("params.mytheme_section.theme_param_nooverride"), qt.Equals, "nooverride")
+               c.Assert(cfg.Get("params.mytheme_section2.theme_param"), qt.Equals, "themevalue2_changed")
+               c.Assert(cfg.Get("params.empty"), qt.Equals, ``)
+               c.Assert(cfg.Get("params.html"), qt.Equals, `<a target="_blank" />`)
+
+               params := cfg.Get("params").(maps.Params)
+               c.Assert(params["paramwithnoenvoverride"], qt.Equals, "nooverride")
+               c.Assert(cfg.Get("params.paramwithnoenvoverride"), qt.Equals, "nooverride")
+               c.Assert(scfg.GoogleAnalytics.ID, qt.Equals, "gaid")
+               c.Assert(cfg.Get("params.a.b"), qt.DeepEquals, maps.Params{
+                       "c": "abc",
+               })
+
+               ofBase, _ := s.outputFormatsConfig.GetByName("ofbase")
+               ofTheme, _ := s.outputFormatsConfig.GetByName("oftheme")
+
+               c.Assert(ofBase.MediaType, qt.Equals, media.TextType)
+               c.Assert(ofTheme.MediaType, qt.Equals, media.TextType)
 
-       cfg := b.H.Cfg
-       s := b.H.Sites[0]
-       scfg := s.siteConfigConfig.Services
-
-       c.Assert(cfg.Get("environment"), qt.Equals, "test")
-       c.Assert(cfg.GetBool("enablegitinfo"), qt.Equals, false)
-       c.Assert(cfg.Get("new"), qt.Equals, "new")
-       c.Assert(cfg.Get("imaging.anchor"), qt.Equals, "top")
-       c.Assert(cfg.Get("imaging.quality"), qt.Equals, int64(75))
-       c.Assert(cfg.Get("imaging.resamplefilter"), qt.Equals, "CatmullRom")
-       c.Assert(cfg.Get("stringSlice"), qt.DeepEquals, []interface{}{"c", "d"})
-       c.Assert(cfg.Get("floatSlice"), qt.DeepEquals, []interface{}{5.32})
-       c.Assert(cfg.Get("intSlice"), qt.DeepEquals, []interface{}{5, 8, 9})
-       c.Assert(cfg.Get("params.api_config.api_key"), qt.Equals, "new_key")
-       c.Assert(cfg.Get("params.api_config.another_key"), qt.Equals, "default another_key")
-       c.Assert(cfg.Get("params.mytheme_section.theme_param"), qt.Equals, "themevalue_changed")
-       c.Assert(cfg.Get("params.mytheme_section.theme_param_nooverride"), qt.Equals, "nooverride")
-       c.Assert(cfg.Get("params.mytheme_section2.theme_param"), qt.Equals, "themevalue2_changed")
-       c.Assert(cfg.Get("params.empty"), qt.Equals, ``)
-       c.Assert(cfg.Get("params.html"), qt.Equals, `<a target="_blank" />`)
-
-       params := cfg.Get("params").(maps.Params)
-       c.Assert(params["paramwithnoenvoverride"], qt.Equals, "nooverride")
-       c.Assert(cfg.Get("params.paramwithnoenvoverride"), qt.Equals, "nooverride")
-       c.Assert(scfg.GoogleAnalytics.ID, qt.Equals, "gaid")
-       c.Assert(cfg.Get("params.a.b"), qt.DeepEquals, maps.Params{
-               "c": "abc",
        })
 
-       ofBase, _ := s.outputFormatsConfig.GetByName("ofbase")
-       ofTheme, _ := s.outputFormatsConfig.GetByName("oftheme")
+       // Issue #8709
+       c.Run("Set in string", func(c *qt.C) {
+               b := newB(c)
+
+               b.WithEnviron(
+                       // imaging.anchor is a string, and it's not possible
+                       // to set a child attribute.
+                       "HUGO_IMAGING_ANCHOR_FOO", "top",
+               )
+
+               b.Build(BuildCfg{})
+
+               cfg := b.H.Cfg
+               c.Assert(cfg.Get("imaging.anchor"), qt.Equals, "smart")
 
-       c.Assert(ofBase.MediaType, qt.Equals, media.TextType)
-       c.Assert(ofTheme.MediaType, qt.Equals, media.TextType)
+       })
 
 }