From fca1441a276aa4ba11c1e4ba7d4647717469d054 Mon Sep 17 00:00:00 2001 From: Mihaela Mihaljevic Date: Wed, 24 Jun 2026 20:10:02 +0200 Subject: [PATCH] fix(parsing): resolve a non-specific '!' tagged scalar as a string The non-specific '!' tag resolves a node by kind alone, with no implicit typing, so '! 12' is the string "12", not the integer 12. The event stream already carried the tag correctly, but typed-value construction fell through to plain-scalar resolution and produced an int. Add the '!' case to tagged-scalar composition so it yields a string. Surpasses libyaml on S4JQ (the last parse-ok gap); whole-suite conformance 391/402, canonical events 308/308. --- CHANGELOG.md | 4 ++++ Sources/Parsing/Parser.ScalarComposition.swift | 4 ++++ Tests/Fixtures/yaml-test-suite-manifest.yaml | 6 +++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8eb9b36..510b08d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Resolve a scalar with the non-specific `!` tag as a string. The `!` tag forces + resolution by kind alone, with no implicit typing, so `! 12` is the string "12" + rather than the integer 12. The typed value now honours it (the event stream + already did). Surpasses libyaml on S4JQ. - Reject a bare `-` before a flow indicator inside a flow collection. Per `ns-plain-first` a `-` begins a plain scalar in flow only when a flow-safe character follows; `[-]` and `[-, -]` are malformed, not a sequence of `-` diff --git a/Sources/Parsing/Parser.ScalarComposition.swift b/Sources/Parsing/Parser.ScalarComposition.swift index a74d68f..70d4355 100644 --- a/Sources/Parsing/Parser.ScalarComposition.swift +++ b/Sources/Parsing/Parser.ScalarComposition.swift @@ -28,6 +28,10 @@ extension PureYAML.Parsing.Parser { return nil } switch tag { + case "!": + // The non-specific `!` tag resolves a scalar by kind alone: a scalar is + // a string, with no implicit typing, so `! 12` is "12" not the int 12. + return .string(value) case "tag:yaml.org,2002:str": return .string(value) case "tag:yaml.org,2002:int": diff --git a/Tests/Fixtures/yaml-test-suite-manifest.yaml b/Tests/Fixtures/yaml-test-suite-manifest.yaml index f8ff897..1bb1ea0 100644 --- a/Tests/Fixtures/yaml-test-suite-manifest.yaml +++ b/Tests/Fixtures/yaml-test-suite-manifest.yaml @@ -10,8 +10,8 @@ source: # oracle: json if in.json present, else none # status: passing (PureYAML conformant today) | gap (not yet conformant) total: 402 -passing: 390 -gap: 12 +passing: 391 +gap: 11 cases: - id: "229Q" name: "Spec Example 2.4. Sequence of Mappings" @@ -2626,7 +2626,7 @@ cases: localPath: yaml-test-suite/S4JQ/in.yaml expected: parse-ok oracle: json - status: gap + status: passing byteCount: 55 lineCount: 4 - id: "S4T7"