Unify trunk on main: initialization → main #3

Merged
jschoubben merged 58 commits from initialization into main 2026-09-05 01:13:33 +00:00
2 changed files with 50 additions and 1 deletions
Showing only changes of commit f9c70a7c97 - Show all commits
+19 -1
View File
@@ -10,6 +10,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"io"
"reflect"
"sort"
"strings"
@@ -569,7 +570,24 @@ func strictDecode(raw []byte, into any) error {
// field the host does not know is a thing the control plane believes it asked for.
dec := json.NewDecoder(bytes.NewReader(raw))
dec.DisallowUnknownFields()
return dec.Decode(into)
if err := dec.Decode(into); err != nil {
return err
}
// And **nothing after it**. A decoder reads one value and stops, so a file holding a
// declaration followed by anything at all — a truncated rewrite, two declarations
// concatenated, a stray line from whatever wrote the file — parses as the first value and the
// rest is never looked at.
//
// That is the same fault this host refuses everywhere else, in its quietest form: the machine
// applies something, reports success, and what it applied is not what the file says. Found
// when a test harness appended a line to a bundle by accident and every apply kept working.
if _, err := dec.Token(); err != io.EOF {
return fmt.Errorf(
"there is more in this file after the declaration ends. Refused whole: a file with " +
"something after it may be a truncated rewrite or two declarations run together, " +
"and applying the first would be applying something nobody wrote")
}
return nil
}
// unknownFields names every JSON key the kind's struct has no field for.
+31
View File
@@ -313,3 +313,34 @@ func TestSomethingInsideAValueIsNotAComment(t *testing.T) {
t.Fatalf("a value was mangled: %q", file.Content)
}
}
// A declaration followed by anything at all is refused whole.
//
// A JSON decoder reads one value and stops, so a file holding a declaration and then a stray line
// parses as the declaration and the rest is never looked at. The machine applies something,
// reports success, and what it applied is not what the file says.
//
// Not hypothetical: a test harness appended a line to the substrate bundle by accident, every
// apply kept working, and nothing said so for the entire time it was wrong.
func TestSomethingAfterTheDeclarationIsRefused(t *testing.T) {
good := `{"declaration":1,"resources":[{"id":"a","type":"file","path":"/tmp/a",` +
`"content":"x","mode":"0644"}]}`
if _, err := ParseFileTrusted([]byte(good)); err != nil {
t.Fatalf("an ordinary declaration was refused: %v", err)
}
for _, after := range []string{
"MESHBUNDLE 2>&1; echo \"__exit=$?\"",
good,
"garbage",
} {
_, err := ParseFileTrusted([]byte(good + "\n" + after))
if err == nil {
t.Fatalf("a file with %q after the declaration was accepted", after)
}
}
// Trailing whitespace is not "something after it", and refusing it would make every file
// written by an editor unusable.
if _, err := ParseFileTrusted([]byte(good + "\n\n \n")); err != nil {
t.Fatalf("a declaration with a trailing newline was refused: %v", err)
}
}