feat: Decoder.DisableTimestamps(bool) opt-out for implicit timestamp resolution#8
Open
reuvenharrison wants to merge 1 commit into
Open
feat: Decoder.DisableTimestamps(bool) opt-out for implicit timestamp resolution#8reuvenharrison wants to merge 1 commit into
reuvenharrison wants to merge 1 commit into
Conversation
…resolution YAML 1.1 auto-resolves unquoted date-shaped scalars (e.g. "1344-08-22") to time.Time, including when they appear as map keys. Real-world specs (OpenAPI / JSON Schema descendants) sometimes use date-shaped strings as map keys, which this auto-resolution silently corrupts: the resulting map has time.Time keys instead of strings, and any downstream string-keyed lookup fails. Add a Decoder.DisableTimestamps(disable bool) option that suppresses the implicit timestamp branch in resolve(). When set, untagged date-shaped scalars resolve to strings. Explicit '!!timestamp' tags in the source still resolve to time.Time, because that is the caller's explicit intent: the flag's purpose is to keep date-shaped UNTAGGED scalars as strings. Plumbing: - Threaded through both the parser (which sets Node.Tag at parse time for untagged scalars) and the internal decoder (which calls resolve when materialising values). - All five resolve() call sites updated; encode-side / yaml.go callers pass false to preserve historical behaviour. - Default Decode() behaviour is unchanged (disableTimestamps defaults to false). Closes invopop/yaml#10 (downstream).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
YAML 1.1 auto-resolves unquoted date-shaped scalars (e.g.
1344-08-22) totime.Time, including when they appear as map keys. Real-world OpenAPI / JSON Schema specs sometimes use date-shaped strings as map keys (e.g.APIs-guru/openapi-directory/APIs/unicourt.com/1.0.0/openapi.yamllines 376-380). The auto-resolution silently turns the parsed value into atime.Time-keyed map, breaking any downstream string-keyed lookup.Closes the gap kin-openapi originally raised in invopop/yaml#10.
API
When set, untagged date-shaped scalars resolve to strings. Explicit
!!timestamptags in the source still resolve totime.Time, because that is the caller's explicit intent: the flag's purpose is to keep date-shaped untagged scalars as strings.Plumbing
disableTimestamps boolfield on the publicDecoder, the internaldecoder, and theparser(the parser tags untagged scalars at parse time, so the flag has to flow there as well).resolve()gets a thirddisableTimestampsparameter. The implicit branch (tag == "" && parseTimestamp(in) ok) is now gated on the flag; the explicittag == timestampTagbranch is unaffected.resolve()call sites updated. Encode-side andyaml.gocallers passfalseto preserve historical behaviour.Decode()behaviour unchanged:disableTimestampsdefaults tofalse.Tests
New
TestDecoderDisableTimestampscovers four cases:1344-08-22"1344-08-22"1344-08-22: hellodecoded intomap[string]string{"1344-08-22": "hello"}!!timestamp 1344-08-22time.Time(explicit tag preserved)1344-08-22time.Time(back-compat)All existing tests pass unchanged.
Downstream
The original request came from kin-openapi via invopop/yaml#10. invopop/yaml is no longer maintained, so kin-openapi switched to
oasdiff/yaml(our fork). That makes this PR the actual fix path for kin-openapi.After this lands and is tagged in
oasdiff/yaml3:oasdiff/yamlexposes the same option onUnmarshal/UnmarshalWithOriginTree.oasdiff/yamlbump.