diff --git a/CHANGELOG.md b/CHANGELOG.md index 4baf415..2b95fb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.0] - 2026-11-15 + ### Fixed - A string no longer changes on the way through YAML or JSON. `PureYAML.dump` wrote control characters, DEL, the C1 controls, U+2028, U+2029, U+FEFF, U+FFFE and U+FFFF as they are, where the reader refused them (`invalid control character`), folded U+0085, U+2028 and U+2029 to a space without a word, or dropped a leading - U+FEFF as a byte order mark. They are now written as the escape that stands for each (`\x01`, `\N`, `\L`, `\P`, ``) and are never written plain or in a - literal block. `PureYAML.JSON.Writer` escapes the same characters (`\u007f`, `
`, and so on), which RFC 8259 allows and a YAML reader needs. + U+FEFF as a byte order mark. They are now written as the escape that stands for each (`\x01`, `\N`, `\L`, `\P`, `\uFEFF`) and are never written plain or in a + literal block. `PureYAML.JSON.Writer` escapes the same characters (`\u007f`, `\u2028`, and so on), which RFC 8259 allows and a YAML reader needs. - A JSON text that holds one of those characters as it is (RFC 8259 allows it) was read as another string, or refused. `PureYAML.JSON.parse(_:)` and `PureYAML.JSON.parseLocated(_:)` read JSON and keep every character of its strings, and `PureYAML.JSON.Convert.convert(_:from:to:pretty:)` takes the format of the source (`from:`, default nil: the source is read as YAML, as before) and reads a JSON source with it. diff --git a/README.md b/README.md index 79678a2..af07286 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ C-backed parsers. The package is intentionally strict about portability: ## Status -The current release is 0.3.0. It includes block mappings, block sequences, +The current release is 0.4.0. It includes block mappings, block sequences, ordered mappings, common scalars, quoted strings, comments, flow collections, literal and folded block scalars, anchors, aliases, YAML directives, document markers, explicit built-in scalar tags, merge-key expansion, complex mapping keys, diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 615b720..10d2430 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -1,8 +1,8 @@ # Release Process -PureYAML versioning is driven by Git tags. The current release is 0.3.0. +PureYAML versioning is driven by Git tags. The current release is 0.4.0. -## 0.3.0 Release +## 0.4.0 Release - Swift tools version: 6.1 - Products: `PureYAML`, `PureYAMLJSON` @@ -10,7 +10,7 @@ PureYAML versioning is driven by Git tags. The current release is 0.3.0. - Source targets: Swift only, no C targets and no generated parser targets - Hosted CI matrix: macOS build and test, Linux build and test, Windows build and test, WASM build -- Release notes file: `docs/releases/pureyaml-0-3-0.md` +- Release notes file: `docs/releases/pureyaml-0-4-0.md` ## Local Verification @@ -59,17 +59,17 @@ Only run these commands after the local gates pass and hosted CI passes. ```sh git status --short --branch -git tag -a 0.3.0 -m "PureYAML 0.3.0" -git push origin main 0.3.0 +git tag -a 0.4.0 -m "PureYAML 0.4.0" +git push origin main 0.4.0 tea releases create --login aleahim --repo NodetteHQ/PureYAML \ - --tag 0.3.0 --title "PureYAML 0.3.0" \ - --note "$(cat docs/releases/pureyaml-0-3-0.md)" + --tag 0.4.0 --title "PureYAML 0.4.0" \ + --note "$(cat docs/releases/pureyaml-0-4-0.md)" ``` After publishing, verify the release exists: ```sh -git ls-remote --tags origin 0.3.0 +git ls-remote --tags origin 0.4.0 tea releases list --login aleahim --repo NodetteHQ/PureYAML | head ``` diff --git a/docs/releases/pureyaml-0-4-0.md b/docs/releases/pureyaml-0-4-0.md new file mode 100644 index 0000000..aa11e4b --- /dev/null +++ b/docs/releases/pureyaml-0-4-0.md @@ -0,0 +1,30 @@ +# PureYAML 0.4.0 + +A release of the string fixes: a string no longer changes on the way through YAML or JSON. It adds three names to the public API and changes what `dump` and the JSON writer write for a few characters, so read the first section before updating. + +## Changed (behavior callers can meet) + +- `PureYAML.dump` writes a string that holds a control character, DEL, a C1 control, U+2028, U+2029, U+FEFF, U+FFFE or U+FFFF as a double-quoted string with the escape that stands for each (`\x01`, `\N`, `\L`, `\P`, `\uFEFF`). It wrote them as they are before, and a reader refused them, folded U+0085, U+2028 and U+2029 to a space without a word, or dropped a leading U+FEFF as a byte order mark. Such a string is never written plain or in a literal block now. Strings without those characters are written as before. +- `PureYAML.JSON.Writer` escapes the same characters (`\u007f`, `\u2028`, and so on), which RFC 8259 allows and a YAML reader needs. The text it writes means the same value; its bytes differ for a string that holds one of them. + +## Added + +- `PureYAML.JSON.parse(_:)` and `PureYAML.JSON.parseLocated(_:)` read JSON and keep every character of its strings, including those RFC 8259 lets a string hold as they are and the YAML reader folds or refuses (U+0085, U+2028, U+2029, U+007F to U+009F, U+FFFE, U+FFFF). Each such character inside a string is held back from the reader as one scalar for one scalar and given back in the value, so every span of `parseLocated` is where the text has it. +- `PureYAML.JSON.Convert.convert(_:from:to:pretty:)` takes the format of the source. With `from: .json` the source is read with `PureYAML.JSON.parse`; without it (the default) the source is read as YAML, as before. + +## Fixed + +- The three faults above, found by an oracle that does not use the reader: a string is held to the value written down for it, because the converter's own check (its reading of the source against its reading of the output) cannot see a fault of the reader that is the same on both sides. + +## Verification + +- macOS: `scripts/check-all.sh` (style, namespacing, forbidden patterns, changelog, swiftformat, swiftlint strict, build and test): 692 tests in 152 suites. +- Linux: build and test through the Linux relay: 692 tests in 152 suites. +- A consumer, PureTree, passes its own suite against this tree: a law that JSON converts to YAML and back with every string kept (300 generated documents, 104 strings and as many keys, 25 numbers, the shapes), and an editor outline of a JSON document that holds those characters. + +## Known deferred issues + +- WASM was NOT built for this release: the `swift-6.3.2-RELEASE_wasm` SDK is not installed on the machine the gate ran on. +- Windows build and test were NOT run: there is no runner for it yet. The tree is pure Swift. +- The reader is still the libyaml port and folds U+0085, U+2028 and U+2029 as line breaks in YAML text, which YAML 1.2 does not. It is unchanged; the fix is in what is written (`dump`) and in reading JSON (`JSON.parse`). +- The hosted CI run of this commit was not watched: this server's API does not list runs, so the authoritative platform gates are the local ones above.