Skip to content

Commit c5555c2

Browse files
committed
fix(engine): tighten isEffectivelyEmptyYAML for indented separators
Previously the function ran bytes.TrimSpace on each line before comparing against "---"/"...", which means an indented " ---" (a YAML scalar inside a parent mapping, not a document separator) would be treated as a separator and hide a real overlay. Compare against the line minus only trailing whitespace instead — separators must be at column 0 per the YAML spec. Comments and blank lines still use the fully trimmed form: a comment can be indented, an empty line is empty regardless of where in the file it appears. Add a regression case to TestNodeFileHasOverlay covering the indented-separator edge. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la>
1 parent 6403d1e commit c5555c2

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

pkg/engine/engine.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,11 @@ func NodeFileHasOverlay(patchFile string) (bool, error) {
261261
// YAML comments, document separators, and whitespace. Used by
262262
// MergeFileAsPatch to detect modeline-only node files that the Talos
263263
// config-patcher misclassifies as empty JSON6902 patches.
264+
//
265+
// Document separators must appear at column 0 per the YAML spec; an
266+
// indented " ---" is a scalar inside a parent mapping, not a
267+
// separator, so the comparison is against the line minus only trailing
268+
// whitespace rather than against the fully trimmed form.
264269
func isEffectivelyEmptyYAML(data []byte) bool {
265270
for _, line := range bytes.Split(data, []byte("\n")) {
266271
trimmed := bytes.TrimSpace(line)
@@ -270,7 +275,8 @@ func isEffectivelyEmptyYAML(data []byte) bool {
270275
if trimmed[0] == '#' {
271276
continue
272277
}
273-
if string(trimmed) == "---" || string(trimmed) == "..." {
278+
untrailed := string(bytes.TrimRight(line, " \t\r"))
279+
if untrailed == "---" || untrailed == "..." {
274280
continue
275281
}
276282
return false

pkg/engine/render_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,16 @@ machine:
12041204
`,
12051205
want: true,
12061206
},
1207+
{
1208+
// A "---" with leading whitespace is not a YAML document
1209+
// separator (separators must be at column 0); it's a
1210+
// scalar inside a parent mapping. Treating it as a
1211+
// separator would misclassify a real overlay as empty
1212+
// and let the multi-node guard be bypassed.
1213+
name: "indented separator counts as overlay",
1214+
content: "# talm: nodes=[\"a\",\"b\"]\nmachine:\n ---\n",
1215+
want: true,
1216+
},
12071217
}
12081218
for _, tt := range tests {
12091219
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)