Repository: gohugoio/hugo (language: go)

Issue:
tpl/transform: Unmarshal whitespace removal produces invalid YAML
This change in v0.136.3 removes whitespace from a YAML string before we unmarshal it:

<https://github.com/gohugoio/hugo/commit/42f37b4e98e6f9621af4f1da40e831525f65fc0e#diff-ac3fd377a127dfceca723e62fdde1176ab715eaa2068402c3e2777a47e409414R115>

I just ran into this in the wild...

```text
{{ $yaml := `
  a:
    b: 1
    c: 2
  d:
    e: 3
    f: 4
`}}

{{ transform.Unmarshal $yaml }}
```

When we remove the leading whitespace, the outermost key is no longer indented, but later keys that should be at the same level are still indented 2 spaces, producing invalid HTML.

> error calling Unmarshal: "_stream.yaml:3:1": failed to unmarshal YAML: yaml: line 3: did not find expected key

Reference: <https://discourse.gohugo.io/t/site-compiled-fine-at-v135-0-but-fails-on-v136-3>



Discussion / hints:

Fix patch:
diff --git a/tpl/transform/unmarshal.go b/tpl/transform/unmarshal.go
index 0068947f6d5..a3a9c040a47 100644
--- a/tpl/transform/unmarshal.go
+++ b/tpl/transform/unmarshal.go
@@ -112,9 +112,8 @@ func (ns *Namespace) Unmarshal(args ...any) (any, error) {
 	if err != nil {
 		return nil, fmt.Errorf("type %T not supported", data)
 	}
-	dataStr = strings.TrimSpace(dataStr)
 
-	if dataStr == "" {
+	if strings.TrimSpace(dataStr) == "" {
 		return nil, nil
 	}
 


Test patch:
diff --git a/tpl/transform/transform_integration_test.go b/tpl/transform/transform_integration_test.go
index da8290e1777..5f34ff81bf5 100644
--- a/tpl/transform/transform_integration_test.go
+++ b/tpl/transform/transform_integration_test.go
@@ -248,7 +248,7 @@ func TestToMathMacros(t *testing.T) {
 -- hugo.toml --
 disableKinds = ['page','rss','section','sitemap','taxonomy','term']
 -- layouts/index.html --
-{{ $macros := dict 
+{{ $macros := dict
     "\\addBar" "\\bar{#1}"
 	"\\bold" "\\mathbf{#1}"
 }}
@@ -261,3 +261,21 @@ disableKinds = ['page','rss','section','sitemap','taxonomy','term']
 <mi>y</mi>
 	`)
 }
+
+// Issue #12977
+func TestUnmarshalWithIndentedYAML(t *testing.T) {
+	t.Parallel()
+
+	files := `
+-- hugo.toml --
+disableKinds = ['page','rss','section','sitemap','taxonomy','term']
+-- layouts/index.html --
+{{ $yaml := "\n  a:\n    b: 1\n  c:\n    d: 2\n" }}
+{{ $yaml | transform.Unmarshal | encoding.Jsonify }}
+`
+
+	b := hugolib.Test(t, files)
+
+	b.AssertFileExists("public/index.html", true)
+	b.AssertFileContent("public/index.html", `{"a":{"b":1},"c":{"d":2}}`)
+}