fix(encode): reject a nil MarshalTOML result

Assisted-by: GLM 5.3
This commit is contained in:
2026-09-17 23:11:10 +02:00
parent d5327568fb
commit 4def1b3e8b
4 changed files with 61 additions and 2 deletions
+33
View File
@@ -383,6 +383,39 @@ func TestMarshalerErrorPropagates(t *testing.T) {
}
}
// nilMarshalerFunc is a Marshaler whose method returns nil with no error.
type nilMarshalerFunc struct{}
func (nilMarshalerFunc) MarshalTOML() (any, error) { return nil, nil }
func TestMarshalRejectsNilMarshalerResult(t *testing.T) {
// nil has no TOML representation, so a MarshalTOML result of nil is an
// error, not a silently dropped field.
_, err := Marshal(struct {
F nilMarshalerFunc `toml:"f"`
}{})
if err == nil {
t.Fatal("expected an error for a nil MarshalTOML result")
}
ee, ok := errors.AsType[*EncodeError](err)
if !ok {
t.Fatalf("expected an *EncodeError, got %T: %v", err, err)
}
if ee.Path != "f" {
t.Fatalf("Path = %q, want %q", ee.Path, "f")
}
// Inside a value array the nil result used to reach reflection as a zero
// Value and panic.
_, err = Marshal(map[string]any{"arr": []any{1, nilMarshalerFunc{}}})
if err == nil {
t.Fatal("expected an error for a nil MarshalTOML result in an array")
}
if !strings.Contains(err.Error(), "MarshalTOML returned a nil value") {
t.Errorf("err = %v, want the nil-result message", err)
}
}
// Two fields that resolve to one TOML key must marshal as one key, resolved
// the way the decoder resolves it, or the output would carry a duplicate key
// and never re-parse.