Skip to content

Hoist XmlWriterSettings and dispose StringWriter in XmlOutputBuilder#713

Merged
tannergooding merged 1 commit into
dotnet:mainfrom
tannergooding:tannergooding-modernize-xmloutputbuilder
Jul 13, 2026
Merged

Hoist XmlWriterSettings and dispose StringWriter in XmlOutputBuilder#713
tannergooding merged 1 commit into
dotnet:mainfrom
tannergooding:tannergooding-modernize-xmloutputbuilder

Conversation

@tannergooding

Copy link
Copy Markdown
Member

Modernizes XmlOutputBuilder.cs with two behavior-preserving cleanups. Generated output is unchanged -- all ~3708 golden tests pass and the build is clean (0 warnings, 0 errors).


Hoist XmlWriterSettings + dispose StringWriter

Contents previously allocated a fresh XmlWriterSettings on every access and leaked the backing StringWriter. The settings are now a private static readonly field constructed once, and both the StringWriter and XmlWriter are wrapped in using scopes. The XmlWriter is disposed (which fully flushes it) before sw.ToString(), so this replaces the old explicit writer.Flush() while producing identical XML -- no truncation.


Replace XText-based escaping with a direct escaper

EscapeText used new XText(value).ToString() solely to XML-escape a string. It now uses a small purpose-built escaper for <, >, and &. This was verified byte-identical to XText.ToString() across every UTF-16 code point plus realistic type names -- the only divergence is raw \r/\n, which XText newline-normalizes and which never appear in the type names EscapeText receives. SecurityElement.Escape was rejected since it escapes a different character set ("/') and does not match XText.

Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com

`Contents` previously allocated a fresh `XmlWriterSettings` on every access
and leaked the backing `StringWriter`. Hoist the settings to a
`private static readonly` field so they are constructed once, and wrap the
`StringWriter` (and the `XmlWriter`) in `using` scopes so both are disposed.
The `XmlWriter` is disposed before `sw.ToString()`, which flushes it fully,
so the produced XML is unchanged (replacing the prior explicit `Flush`).

Also replace `new XText(value).ToString()` in `EscapeText` with a small
purpose-built escaper for `<`, `>`, and `&`. This was verified byte-identical
to `XText.ToString()` for every input except raw `\r`/`\n` (which `XText`
newline-normalizes and which never appear in the type names `EscapeText`
receives), so generated output is unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@tannergooding
tannergooding merged commit bc96c95 into dotnet:main Jul 13, 2026
11 checks passed
@tannergooding
tannergooding deleted the tannergooding-modernize-xmloutputbuilder branch July 13, 2026 02:33
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.

1 participant