Skip to content

Commit 329b234

Browse files
committed
Fix "concurrent map iteration and map write" in pages from data
Fixes #13254
1 parent 33b46d8 commit 329b234

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

common/maps/maps_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,14 @@ func TestPrepareParams(t *testing.T) {
7373
for i, test := range tests {
7474
t.Run(fmt.Sprint(i), func(t *testing.T) {
7575
// PrepareParams modifies input.
76+
prepareClone := PrepareParamsClone(test.input)
7677
PrepareParams(test.input)
7778
if !reflect.DeepEqual(test.expected, test.input) {
7879
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, test.input)
7980
}
81+
if !reflect.DeepEqual(test.expected, prepareClone) {
82+
t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, prepareClone)
83+
}
8084
})
8185
}
8286
}

common/maps/params.go

+40-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ func toMergeStrategy(v any) ParamsMergeStrategy {
303303
}
304304

305305
// PrepareParams
306-
// * makes all the keys in the given map lower cased and will do so
306+
// * makes all the keys in the given map lower cased and will do so recursively.
307307
// * This will modify the map given.
308308
// * Any nested map[interface{}]interface{}, map[string]interface{},map[string]string will be converted to Params.
309309
// * Any _merge value will be converted to proper type and value.
@@ -343,3 +343,42 @@ func PrepareParams(m Params) {
343343
}
344344
}
345345
}
346+
347+
// PrepareParamsClone is like PrepareParams, but it does not modify the input.
348+
func PrepareParamsClone(m Params) Params {
349+
m2 := make(Params)
350+
for k, v := range m {
351+
var retyped bool
352+
lKey := strings.ToLower(k)
353+
if lKey == MergeStrategyKey {
354+
v = toMergeStrategy(v)
355+
retyped = true
356+
} else {
357+
switch vv := v.(type) {
358+
case map[any]any:
359+
var p Params = cast.ToStringMap(v)
360+
v = PrepareParamsClone(p)
361+
retyped = true
362+
case map[string]any:
363+
var p Params = v.(map[string]any)
364+
v = PrepareParamsClone(p)
365+
retyped = true
366+
case map[string]string:
367+
p := make(Params)
368+
for k, v := range vv {
369+
p[k] = v
370+
}
371+
v = p
372+
PrepareParams(p)
373+
retyped = true
374+
}
375+
}
376+
377+
if retyped || k != lKey {
378+
m2[lKey] = v
379+
} else {
380+
m2[k] = v
381+
}
382+
}
383+
return m2
384+
}

resources/page/pagemeta/page_frontmatter.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,11 @@ func (p *PageConfig) Compile(basePath string, pagesFromData bool, ext string, lo
158158

159159
if p.Params == nil {
160160
p.Params = make(maps.Params)
161+
} else if pagesFromData {
162+
p.Params = maps.PrepareParamsClone(p.Params)
163+
} else {
164+
maps.PrepareParams(p.Params)
161165
}
162-
maps.PrepareParams(p.Params)
163166

164167
if p.Content.Markup == "" && p.Content.MediaType == "" {
165168
if ext == "" {

0 commit comments

Comments
 (0)