From 32027e50a1d6645a5fa270158079d267ef93acc1 Mon Sep 17 00:00:00 2001 From: khayyam Date: Mon, 16 Feb 2026 11:32:45 -0500 Subject: [PATCH] paths: Fix handling of _ as a path name Fixes #14344 --- common/paths/pathparser.go | 16 ++++++++++++---- hugolib/site_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/common/paths/pathparser.go b/common/paths/pathparser.go index fbba141b8..5d828df14 100644 --- a/common/paths/pathparser.go +++ b/common/paths/pathparser.go @@ -30,10 +30,18 @@ import ( ) const ( - identifierBaseof = "baseof" - identifierCurstomWrapper = "_" + identifierBaseof = "baseof" + identifierCustomWrapper = "_" ) +// isCustomWrapperIdentifier tells whether a supplied path is of the form _xyz_. +// must have non-empty content between the identifierCustomWrapper's to pass. +func isCustomWrapperIdentifier(s string) bool { + return len(s) > 2*len(identifierCustomWrapper) && + strings.HasPrefix(s, identifierCustomWrapper) && + strings.HasSuffix(s, identifierCustomWrapper) +} + // PathParser parses and manages paths. type PathParser struct { // Maps the language code to its index in the languages/sites slice. @@ -188,7 +196,7 @@ func (pp *PathParser) parseIdentifier(component, s string, p *Path, i, lastDot, id := types.LowHigh[string]{Low: i + 1, High: high} sid := p.s[id.Low:id.High] - if strings.HasPrefix(sid, identifierCurstomWrapper) && strings.HasSuffix(sid, identifierCurstomWrapper) { + if isCustomWrapperIdentifier(sid) { p.identifiersKnown = append(p.identifiersKnown, id) p.posIdentifierCustom = len(p.identifiersKnown) - 1 found = true @@ -775,7 +783,7 @@ func (p *Path) Lang() string { } func (p *Path) Custom() string { - return strings.TrimSuffix(strings.TrimPrefix(p.identifierAsString(p.posIdentifierCustom), identifierCurstomWrapper), identifierCurstomWrapper) + return strings.TrimSuffix(strings.TrimPrefix(p.identifierAsString(p.posIdentifierCustom), identifierCustomWrapper), identifierCustomWrapper) } func (p *Path) Identifier(i int) string { diff --git a/hugolib/site_test.go b/hugolib/site_test.go index 01da9d6b8..dc9f14148 100644 --- a/hugolib/site_test.go +++ b/hugolib/site_test.go @@ -458,6 +458,33 @@ Content: {{ .Content }} b.AssertFileContent("public/post/nested-a/content-a/index.html", `Content: http://example.com/post/nested-b/content-b/`) } +// Issue 14344 +func TestRefUnderscoreSection(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +baseURL = 'https://example.org/' +-- layouts/home.html -- +{{ .Content }} +-- content/_index.md -- +--- +title: home +--- +{{% ref "definitions/_" %}} +-- content/definitions/_/_index.md -- +--- +title: underscore +--- +` + + b := Test(t, files) + + b.AssertFileContent("public/index.html", + `https://example.org/definitions/_/`, + ) +} + func TestClassCollector(t *testing.T) { for _, minify := range []bool{false, true} { t.Run(fmt.Sprintf("minify-%t", minify), func(t *testing.T) { -- 2.39.5