Reject trailing record JSON without decoding a second value

This commit is contained in:
2026-11-02 22:37:12 +00:00
parent 3b8bacf114
commit cd274512e7
3 changed files with 39 additions and 7 deletions

View File

@@ -138,6 +138,38 @@ func TestLoadEvidenceAcceptsPartialAndRejectsMalformedRecords(t *testing.T) {
}
}
func TestLoadEvidenceRequiresOneDocumentAndPreservesSyntaxCause(t *testing.T) {
const valid = `{"format_version":1,"evidence":{"tag":"v1.2.3","future":{}},"future":true}`
for _, test := range []struct {
name, data string
valid bool
}{
{"single", valid, true}, {"whitespace", valid + "\n \t\r", true},
{"first incomplete", "{", false}, {"first syntax", "x", false},
{"second object", valid + ` {"unused":[1,2,3]}`, false},
{"incomplete suffix", valid + " {", false}, {"invalid suffix", valid + " x", false},
} {
t.Run(test.name, func(t *testing.T) {
path := filepath.Join(t.TempDir(), "record.json")
if err := os.WriteFile(path, []byte(test.data), 0600); err != nil {
t.Fatal(err)
}
loaded, err := LoadEvidence(path)
if test.valid {
if err != nil || loaded.Tag != "v1.2.3" {
t.Fatalf("valid record = %#v, %v", loaded, err)
}
return
}
var recovery *RecoveryError
var syntax *json.SyntaxError
if !errors.As(err, &recovery) || recovery.Kind != "record_format" || !errors.As(err, &syntax) {
t.Fatalf("lost format/parser cause: %v", err)
}
})
}
}
func TestLoadEvidenceReadFailureHasTypedError(t *testing.T) {
_, err := LoadEvidence(filepath.Join(t.TempDir(), "missing.json"))
var recovery *RecoveryError