Last 12 weeks · 8 commits
2 of 6 standards met
This tightens by doing two small things: grow the from the key parts instead of the previous heuristic scan for TOML bare-key characters by byte, since bare keys are ASCII-only The public behavior should be unchanged. I also checked the patch with a temporary differential test that compared the new and implementations against the previous rune-scanning implementation over fixed edge cases, empty keys, Unicode, invalid UTF-8 bytes, and 5,000 deterministic randomized keys. Validation: Benchmark command: : I found the candidate while experimenting with Sleepy - https://sleepy.run, then manually reduced the generated diff and validated it locally.
The inline-table cases under internal/toml-test were already on the skip list with a "we allow appending to tables, but shouldn't" note, which is what put me onto this. valueInlineTable builds the table and hands back its map, but nothing records that an inline table is a closed, self-contained definition, so a later table header or dotted key walks straight back into it. then , then , and all parse without error even though the spec says an inline table cannot be extended once its braces close. Unfixed, this silently accepts malformed documents and mutates a value the author meant to be immutable. I record each inline table's full key path in a closed set the moment it finishes building, and reject extension where the traversal actually happens: the parent descent in addContext (table headers) and addImplicitContext (dotted keys). Arrays of tables reuse the same key path for every element, so a new element clears the closed entries beneath it, otherwise the second [[arr]] element would wrongly inherit the first element's inline tables. Putting the check next to the traversal covers both the header and dotted-key routes in one spot rather than at each call site. Six toml-test invalid fixtures that were skipped for this reason now pass.
I have a use case where I'm unmarshaling several files in a directory. For each file I unmarshal, I want values in the file to overwrite values from previous files, but leave all of the other data as is. That works already for structs, but when unmarshaling to a map it would lose data. As far as I could tell, it's just maps - types that implement Unmarshaler work as I expected, structs work as I expected, slices get replaced but that also seems correct. Since this change could potentially break existing uses, I've hidden the behavior behind . If you don't tell the decoder to merge data, it works the same as before. I've added a test, but some rough repro steps: 1. Create a map of "default" data: 2. Unmarshal a file to the map from [1]: 3. Check what I expected: what I saw:
Summary Fixes #451 When a dotted key like implicitly creates table , a subsequent scalar assignment should be rejected since is already defined as a table, not silently accepted. The fix adds a type check in when allowing implicit-to-explicit promotion: only (tables) are accepted. Scalars and arrays are rejected with the existing "Key has already been defined" error. Test plan [x] Added regression test in for the case [x] Verified still works ( — table redefines implicit table) [x] Verified table redefines implicit table via header still works () [x] All existing tests pass () [x] clean
I noticed that local datetimes, dates, and times don't survive a round trip on any machine that isn't in UTC: decoding then re-encoding shifts the value by the local timezone offset. A local time of comes back as , and a near-midnight local datetime can even roll over to a different day. These types have no offset, so their value is the literal wall-clock time — the decoder already stores it that way via , but the encoder ran before formatting, which moved the wall clock. The fix formats the wall-clock value directly. I also updated the helper's to build local times with so it constructs them the same way the decoder does (the previous and the encoder's UTC shift were cancelling each other out, which is why the conformance suite didn't catch this). Tests pass under several timezones (, , ); added a round-trip test for the local types. The existing round-trip harness didn't surface this because it only re-decodes the output, it doesn't compare values.
Repository: BurntSushi/toml. Description: TOML parser for Golang with reflection. Stars: 4980, Forks: 554. Primary language: Go. Languages: Go (100%). License: MIT. Latest release: v1.6.0 (6mo ago). Open PRs: 10, open issues: 18. Last activity: 6d ago. Community health: 42%. Top contributors: arp242, BurntSushi, cespare, sqs, kkHAIKE, rjeczalik, ttacon, spf13, sahvx655-wq, martinlindhe and others.