Escape string literals that contain line breaks#908
Open
adityasingh2400 wants to merge 1 commit into
Open
Conversation
The text renderer emitted string literals on a single line, choosing between a raw literal and a plain literal based only on whether the content had a quote or backslash. Neither a raw nor a plain single-line literal can contain a line break, so any string value with a newline or carriage return produced an unterminated string literal that does not compile. This happens, for example, when a string enum case value in the OpenAPI document contains a newline: the generated `rawValue` spanned two lines and the file failed to build. Detect line breaks first and, in that case, emit an escaped regular literal that represents the break with `\n` or `\r` (also escaping backslashes and quotes). All other strings keep the existing raw-literal behavior, so no current output changes.
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.
When the renderer emits a string literal, it currently picks between a raw literal and a plain literal based only on whether the content contains a quote or a backslash. But neither a raw nor a plain single-line literal can contain a line break, so any string value with a newline or carriage return is rendered across multiple lines and produces an unterminated string literal that does not compile.
Motivation
A string enum whose value contains a newline triggers this. For example:
generates:
which fails to compile with
error: unterminated string literal. The same applies anywhere a.stringliteral carries a line break, including a string with both a quote and a newline, where the existing raw-literal path is chosen but still cannot span lines.Modifications
renderLiteralnow checks for a line feed or carriage return first. When the content has one, it emits an escaped regular literal that represents the break with\nor\r(also escaping backslashes and quotes so the value round-trips). Every other string keeps the existing raw-literal behavior, so no current output changes.The example above now renders as a single valid line:
Result
Specs with line breaks in string values, such as enum cases, now generate compiling Swift whose values match the input byte for byte.
Test Plan
Added unit tests in
Test_TextBasedRenderercovering a newline, a newline combined with a quote, a carriage return, and a backslash followed by a newline. They fail before the change and pass after. The existing reference and Petstore suites are unchanged.