Skip to content

Escape control characters in generated C# string literals [patch] - #226

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/217-quote-control-characters
Sep 29, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix/217-quote-control-characters

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #217

What was wrong

CSharpCodeGenerator.Quote escaped only \ and ". It builds the String default initialiser, the SchemaDefault(...) argument, and the SchemaUnit / SchemaEditorHint arguments. A value containing a newline therefore produced a raw line break inside a regular literal. Generation reported success, but the output failed to compile with CS1010: Newline in constant. A tab or NUL did compile, but ended up in the source as an invisible raw character.

Change

Quote now escapes, character by character:

  • \ and ", as before
  • \n, \r, \t and \0 with their short escapes
  • anything else below U+0020 as \uXXXX
  • U+0085, U+2028 and U+2029 as \uXXXX. C# treats these as line terminators, so they would also break a literal

This is the set the C++ Escape already handles, plus the Unicode line separators. I didn't add a Roslyn dependency to the library for SymbolDisplay.FormatLiteral.

Tests

CodeGenerationRoundTripTests.TestAStringDefaultWithControlCharactersCompilesAndKeepsItsValue generates a class whose String default contains \n, \r\n, \t, \0, U+0001, U+2028, a quote and a backslash. It then:

  • compiles the output
  • checks that a new instance's property holds exactly that string
  • checks that the reimported SchemaDefault holds exactly that string

With the CSharpCodeGenerator.cs change reverted, the test fails with Note.g.cs(11,37): error CS1010: Newline in constant, on both the attribute line and the initialiser line. With the change, the full Schema.Test suite passes on net10.0 (503/503). I couldn't run the net8.0/net9.0 legs because those runtimes aren't installed in this environment.

🤖 Generated with Claude Code

https://claude.ai/code/session_011PMSp3sjbza8Td6fxS2Kjr


Generated by Claude Code

CSharpCodeGenerator.Quote escaped only backslash and double quote, so a
String default, unit or editor hint containing a newline produced a raw
line break inside the literal (CS1010), and a tab or NUL landed in the
source as an invisible raw character. Escape \n \r \t \0, anything else
below U+0020 as \uXXXX, and the line separators U+0085, U+2028 and U+2029.

Fixes #217

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011PMSp3sjbza8Td6fxS2Kjr
…-characters

# Conflicts:
#	Schema.Test/CodeGenerationRoundTripTests.cs
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 6ead1dc into main Sep 29, 2026
12 checks passed
@matt-edmondson
matt-edmondson deleted the fix/217-quote-control-characters branch September 29, 2026 07:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C# generator emits uncompilable code (CS1010) for a String default, unit or editor hint containing a newline or other control character

2 participants