hugolib: Fix possible .Content cut

There have been one report of a site with truncated `.Content` after the Hugo `0.40.1` release.

This commit fixes this so that race should not be possible anymore. It also adds a stress test with focus on content rendering and multiple output formats.

Fixes #4706
This commit is contained in:
Bjørn Erik Pedersen
2018-05-08 10:10:13 +02:00
parent c2bb62d63e
commit 086ae81a98
8 changed files with 191 additions and 56 deletions

View File

@@ -416,7 +416,6 @@ type pageInit struct {
languageInit sync.Once
pageMenusInit sync.Once
pageMetaInit sync.Once
pageOutputInit sync.Once
renderingConfigInit sync.Once
withoutContentInit sync.Once
}
@@ -1178,6 +1177,24 @@ func (p *Page) subResourceTargetPathFactory(base string) string {
return path.Join(p.relTargetPathBase, base)
}
func (p *Page) initMainOutputFormat() error {
if p.mainPageOutput != nil {
return nil
}
outFormat := p.outputFormats[0]
pageOutput, err := newPageOutput(p, false, false, outFormat)
if err != nil {
return fmt.Errorf("Failed to create output page for type %q for page %q: %s", outFormat.Name, p.pathOrTitle(), err)
}
p.mainPageOutput = pageOutput
return nil
}
func (p *Page) setContentInit(start bool) error {
if start {
@@ -1962,12 +1979,17 @@ func (p *Page) updatePageDates() {
// copy creates a copy of this page with the lazy sync.Once vars reset
// so they will be evaluated again, for word count calculations etc.
func (p *Page) copy() *Page {
func (p *Page) copy(initContent bool) *Page {
p.contentInitMu.Lock()
c := *p
p.contentInitMu.Unlock()
c.pageInit = &pageInit{}
c.pageContentInit = &pageContentInit{}
if initContent {
if len(p.outputFormats) < 2 {
panic(fmt.Sprintf("programming error: page %q should not need to rebuild content as it has only %d outputs", p.Path(), len(p.outputFormats)))
}
c.pageContentInit = &pageContentInit{}
}
return &c
}