Fix block scalar chomping edge case for EOF without newline - #2454
Fix block scalar chomping edge case for EOF without newline#2454jonasfj wants to merge 2 commits into
Conversation
Package publishingIf you have publishing permissions, you can use the links below to publish the changes after merging this PR.
Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation. |
PR HealthUnused Dependencies ✔️
For details on how to fix these, see dependency_validator. This check can be disabled by tagging the PR with Breaking changes ✔️
This check can be disabled by tagging the PR with Changelog Entry ✔️
Changes to files need to be accounted for in their respective changelogs. This check can be disabled by tagging the PR with Coverage ✔️
This check for test coverage is informational (issues shown here will not fail the PR). This check can be disabled by tagging the PR with License Headers ✔️
All source files should start with a license header. This check can be disabled by tagging the PR with |
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
|
From reading the changed YAML files on pub.dev, I'd suggest we have:
|
ba51b74 to
5a3c6e6
Compare
|
Added |
TAG=agy CONV=3c3f08d3-a81d-4074-800b-7df81ce392ae
| @@ -1190,7 +1190,11 @@ class Scanner { | |||
| // libyaml always reads a line here, but this breaks on block scalars at | |||
| // the end of the document that end without newlines. See example 8.1: | |||
| // http://yaml.org/spec/1.2/spec.html#id2793888. | |||
The YAML 1.2.2 specification (Section 8.1.1.2: Block Chomping Indicator) defines the rules for handling final line breaks in block scalars. The production rule
[165] b-chomped-last(t)dictates that when a block scalar terminates at the end of a file (<end-of-input>), the EOF itself acts identically to a physical line break (b-as-line-feed). Therefore, under the default "clip" chomping behavior, this implicit final line break must be retained as part of the string content.Detailed specification references
The YAML 1.2.2 specification says about this in Section 8.1.1.2: Block Chomping Indicator.
The specification explicitly addresses how the final line break of a block scalar is handled, even if the file abruptly ends.
The Chomping Indicators
The spec defines the three possible chomping behaviors (production
[164]):If you write
|-, it's STRIP. If you write|+, it's KEEP. If you just write|(an empty string for the indicator), it defaults to CLIP.The Final Line Break Rule
The spec explains how the very last character of the block scalar is evaluated (production
[165]):Explanation of Rule
[165]The grammar for the default CLIP chomping is:
b-chomped-last(CLIP) ::= b-as-line-feed | <end-of-input>This means that to successfully complete a block scalar under CLIP chomping, the parser must encounter EITHER:
b-as-line-feed(a physical newline character like\n).<end-of-input>(the physical end of the file/stream).Because they are both valid, parallel branches of the exact same production rule (
b-chomped-last(CLIP)), the parser is mathematically required to treat<end-of-input>as functionally identical to a physical line feed for the purpose of concluding the string.Implications for users
If a user writes:
And they omit the final trailing newline, the parser hits
<end-of-input>. Because<end-of-input>fulfills theb-chomped-last(CLIP)requirement in the exact same way a physical line feed would, the parser must inject/retain the\nin the final parsed JSON (resulting in"text\n"), pretending the line feed was there.Fix
leadingBreaknow explicitly defaults to\nwhen the scanner hits EOF, ensuring the spec-mandated implicit final newline is preserved under default clip chomping rules.L24T-1from_expectedFailuresas it now passes.Implications
View diffs for the 310 changed YAML files.