mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-18 21:11:19 +02:00
Fix "concurrent map iteration and map write" in pages from data
Fixes #13254
This commit is contained in:
@@ -73,10 +73,14 @@ func TestPrepareParams(t *testing.T) {
|
|||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
||||||
// PrepareParams modifies input.
|
// PrepareParams modifies input.
|
||||||
|
prepareClone := PrepareParamsClone(test.input)
|
||||||
PrepareParams(test.input)
|
PrepareParams(test.input)
|
||||||
if !reflect.DeepEqual(test.expected, test.input) {
|
if !reflect.DeepEqual(test.expected, test.input) {
|
||||||
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, test.input)
|
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, test.input)
|
||||||
}
|
}
|
||||||
|
if !reflect.DeepEqual(test.expected, prepareClone) {
|
||||||
|
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, prepareClone)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -303,7 +303,7 @@ func toMergeStrategy(v any) ParamsMergeStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PrepareParams
|
// PrepareParams
|
||||||
// * makes all the keys in the given map lower cased and will do so
|
// * makes all the keys in the given map lower cased and will do so recursively.
|
||||||
// * This will modify the map given.
|
// * This will modify the map given.
|
||||||
// * Any nested map[interface{}]interface{}, map[string]interface{},map[string]string will be converted to Params.
|
// * Any nested map[interface{}]interface{}, map[string]interface{},map[string]string will be converted to Params.
|
||||||
// * Any _merge value will be converted to proper type and value.
|
// * Any _merge value will be converted to proper type and value.
|
||||||
@@ -343,3 +343,42 @@ func PrepareParams(m Params) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrepareParamsClone is like PrepareParams, but it does not modify the input.
|
||||||
|
func PrepareParamsClone(m Params) Params {
|
||||||
|
m2 := make(Params)
|
||||||
|
for k, v := range m {
|
||||||
|
var retyped bool
|
||||||
|
lKey := strings.ToLower(k)
|
||||||
|
if lKey == MergeStrategyKey {
|
||||||
|
v = toMergeStrategy(v)
|
||||||
|
retyped = true
|
||||||
|
} else {
|
||||||
|
switch vv := v.(type) {
|
||||||
|
case map[any]any:
|
||||||
|
var p Params = cast.ToStringMap(v)
|
||||||
|
v = PrepareParamsClone(p)
|
||||||
|
retyped = true
|
||||||
|
case map[string]any:
|
||||||
|
var p Params = v.(map[string]any)
|
||||||
|
v = PrepareParamsClone(p)
|
||||||
|
retyped = true
|
||||||
|
case map[string]string:
|
||||||
|
p := make(Params)
|
||||||
|
for k, v := range vv {
|
||||||
|
p[k] = v
|
||||||
|
}
|
||||||
|
v = p
|
||||||
|
PrepareParams(p)
|
||||||
|
retyped = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if retyped || k != lKey {
|
||||||
|
m2[lKey] = v
|
||||||
|
} else {
|
||||||
|
m2[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m2
|
||||||
|
}
|
||||||
|
@@ -158,8 +158,11 @@ func (p *PageConfig) Compile(basePath string, pagesFromData bool, ext string, lo
|
|||||||
|
|
||||||
if p.Params == nil {
|
if p.Params == nil {
|
||||||
p.Params = make(maps.Params)
|
p.Params = make(maps.Params)
|
||||||
|
} else if pagesFromData {
|
||||||
|
p.Params = maps.PrepareParamsClone(p.Params)
|
||||||
|
} else {
|
||||||
|
maps.PrepareParams(p.Params)
|
||||||
}
|
}
|
||||||
maps.PrepareParams(p.Params)
|
|
||||||
|
|
||||||
if p.Content.Markup == "" && p.Content.MediaType == "" {
|
if p.Content.Markup == "" && p.Content.MediaType == "" {
|
||||||
if ext == "" {
|
if ext == "" {
|
||||||
|
Reference in New Issue
Block a user