fix(decode): let the later field win an equal-depth name clash
Assisted-by: GLM 5.3
This commit is contained in:
@@ -58,6 +58,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
is not valid UTF-8, the way scalar keys already did, instead of silently
|
is not valid UTF-8, the way scalar keys already did, instead of silently
|
||||||
emitting corrupt TOML (a header that lost its key, an inline table with a
|
emitting corrupt TOML (a header that lost its key, an inline table with a
|
||||||
missing key).
|
missing key).
|
||||||
|
- Struct fields that resolve to one key at equal depth decode through the
|
||||||
|
field declared later, matching the documented rule; the first one won before.
|
||||||
- A float with an exponent marker but no digits (`1e`, `0.0E`) is rejected;
|
- A float with an exponent marker but no digits (`1e`, `0.0E`) is rejected;
|
||||||
the exponent requires at least one digit.
|
the exponent requires at least one digit.
|
||||||
- A date-time offset outside 00:00 through 23:59 is rejected; such offsets
|
- A date-time offset outside 00:00 through 23:59 is rejected; such offsets
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ func newStructSchema(t reflect.Type) structSchema {
|
|||||||
name = f.Name
|
name = f.Name
|
||||||
}
|
}
|
||||||
key := strings.ToLower(name)
|
key := strings.ToLower(name)
|
||||||
if existing, ok := s.byName[key]; !ok || depth < existing.depth {
|
if existing, ok := s.byName[key]; !ok || depth <= existing.depth {
|
||||||
s.byName[key] = structFieldLoc{index: path, depth: depth}
|
s.byName[key] = structFieldLoc{index: path, depth: depth}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -586,6 +586,22 @@ func TestUnmarshalEmbeddedNameClashShallowerWins(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalNameClashEqualDepthLaterWins(t *testing.T) {
|
||||||
|
// At equal depth the field declared later resolves the name, matching the
|
||||||
|
// documented rule.
|
||||||
|
type C struct {
|
||||||
|
First string `toml:"v"`
|
||||||
|
Second int `toml:"v"`
|
||||||
|
}
|
||||||
|
var c C
|
||||||
|
if err := Unmarshal([]byte("v = 1\n"), &c); err != nil {
|
||||||
|
t.Fatalf("unmarshal: %v", err)
|
||||||
|
}
|
||||||
|
if c.Second != 1 {
|
||||||
|
t.Fatalf("decoded: %+v, want the later field to take the value", c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUnmarshalUnknownKeyWithoutEmbeddedMap(t *testing.T) {
|
func TestUnmarshalUnknownKeyWithoutEmbeddedMap(t *testing.T) {
|
||||||
var cfg RoundTripDerived
|
var cfg RoundTripDerived
|
||||||
if err := Unmarshal([]byte("rogue = 1\n"), &cfg); err != nil {
|
if err := Unmarshal([]byte("rogue = 1\n"), &cfg); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user