]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Fix index out of range panic in fileEventsContentPaths
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 27 Feb 2026 09:21:12 +0000 (10:21 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 27 Feb 2026 11:05:13 +0000 (12:05 +0100)
The nested loop had dirs as the outer loop and others as the inner loop
with a single counter, causing n to exceed len(others) when multiple
dirs existed. Swap the loop order so each file in others is checked
against all dirs exactly once.

Fixes #14573

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
hugolib/integrationtest_builder.go
hugolib/rebuild_test.go
hugolib/site.go

index ed558cbaf66b6a2a0ccc62ec50f1e0fbee15d757..c08a86c472125d645f775b638dfd8b942c70450e 100644 (file)
@@ -751,6 +751,15 @@ func (s *IntegrationTestBuilder) AddFiles(filenameContent ...string) *Integratio
        return s
 }
 
+func (s *IntegrationTestBuilder) CreateDirs(dirnames ...string) *IntegrationTestBuilder {
+       for _, dirname := range dirnames {
+               absDir := s.absFilename(filepath.FromSlash(dirname))
+               s.Assert(s.fs.Source.MkdirAll(absDir, 0o777), qt.IsNil)
+               s.createdFiles = append(s.createdFiles, absDir)
+       }
+       return s
+}
+
 func (s *IntegrationTestBuilder) RemoveFiles(filenames ...string) *IntegrationTestBuilder {
        for _, filename := range filenames {
                absFilename := s.absFilename(filename)
index afa8e326c2a37c5e70cad5fc2077bb5d6de22533..bf2c13a3cbb342754623e8d7882cde9e01ce5530 100644 (file)
@@ -399,6 +399,33 @@ func TestRebuilErrorRecovery(t *testing.T) {
        b.EditFileReplaceAll("content/mysection/mysectionbundle/index.md", "{{< foo }}", "{{< foo >}}").Build()
 }
 
+// Issue 14573
+func TestRebuildAddContentWithMultipleDirCreations(t *testing.T) {
+       t.Parallel()
+       files := `
+-- hugo.toml --
+baseURL = "https://example.com"
+disableLiveReload = true
+-- content/p1.md --
+---
+title: "P1"
+---
+-- layouts/page.html --
+Single: {{ .Title }}|{{ .Content }}|
+-- layouts/list.html --
+Pages: {{ range .RegularPages }}{{ .RelPermalink }}|{{ end }}$
+`
+       b := TestRunning(t, files)
+       b.AssertFileContent("public/index.html", "Pages: /p1/|$")
+       b.AddFiles(
+               "content/nesteddir/dir1/post.md", "---\ntitle: Post\n---",
+       ).CreateDirs(
+               "content/dir1",
+               "content/dir2",
+       ).Build()
+       b.AssertFileContent("public/nesteddir/dir1/post/index.html", "Single: Post|")
+}
+
 func TestRebuildAddPageListPagesInHome(t *testing.T) {
        files := `
 -- hugo.toml --
index 07fe41d2a0fa5e2f2027ba6194a70d57c37e1638..3ceccc440ae9ea73336fd6ae8a2e5dff3c7e57f8 100644 (file)
@@ -1316,15 +1316,18 @@ func (h *HugoSites) fileEventsContentPaths(p []pathChange) []pathChange {
        // Remove all files below dir.
        if len(dirs) > 0 {
                n := 0
-               for _, d := range dirs {
-                       dir := d.p.Path() + "/"
-                       for _, o := range others {
-                               if !strings.HasPrefix(o.p.Path(), dir) {
-                                       others[n] = o
-                                       n++
+               for _, o := range others {
+                       keep := true
+                       for _, d := range dirs {
+                               if strings.HasPrefix(o.p.Path(), d.p.Path()+"/") {
+                                       keep = false
+                                       break
                                }
                        }
-
+                       if keep {
+                               others[n] = o
+                               n++
+                       }
                }
                others = others[:n]
        }