Skip to content

Add regression coverage for metadata newline preservation - #14261

Merged
VolPlita merged 2 commits into
dotnet:mainfrom
VolPlita:fix-4083-newline-regression-tests
Jul 8, 2026
Merged

VolPlita merged 2 commits into
dotnet:mainfrom
VolPlita:fix-4083-newline-regression-tests

Conversation

@VolPlita

@VolPlita VolPlita commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Fixes #4083

Context

This change strengthens regression coverage around newline handling in project file parsing.

Historically, switching from XmlTextReader to XmlReader.Create in read-only load paths caused newline/whitespace normalization changes that broke multiline metadata and command scenarios. This PR adds coverage and clarifies why the current reader choice is intentional for compatibility.

Changes Made

  • Added regression tests in src/Build.UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs to verify multiline metadata with CRLF is preserved:
    • when loading from disk
    • when loading through read-only project loading (loadProjectsReadOnly: true)
  • Refactored duplicated test XML setup into a shared helper method.
  • Updated the compatibility comment in src/Build/Xml/XmlReaderExtension.cs to clearly document why XmlTextReader is used and linked related issues (#4210, #4213, #4083, #6232, #6669).

Testing

  • Ran XmlReaderWithoutLocation_Tests and validated the new regression tests pass.
  • Ran existing multiline Exec regression tests to ensure related behavior remains covered.

Notes

This PR does not change runtime parsing behavior; it improves documentation and regression protection for existing compatibility behavior.

Copilot AI review requested due to automatic review settings July 3, 2026 15:32
@VolPlita
VolPlita temporarily deployed to copilot-pat-pool July 3, 2026 15:32 — with GitHub Actions Inactive
@VolPlita
VolPlita temporarily deployed to copilot-pat-pool July 3, 2026 15:33 — with GitHub Actions Inactive
@VolPlita
VolPlita temporarily deployed to copilot-pat-pool July 3, 2026 15:33 — with GitHub Actions Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds regression tests to ensure MSBuild’s XML loading path continues to preserve multi-line item metadata values (notably CRLF sequences), and updates an in-code compatibility comment explaining why MSBuild continues using XmlTextReader instead of XmlReader.Create to avoid whitespace/newline normalization behavior changes.

Changes:

  • Expanded the compatibility comment in XmlReaderExtension to document newline/whitespace preservation rationale and link related history.
  • Added Windows-only regression tests that load a project from disk (including “read-only” load) and assert CRLF preservation in item metadata.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/Build/Xml/XmlReaderExtension.cs Updates compatibility commentary around XML reader choice to explain newline/whitespace behavior impact.
src/Build.UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs Adds regression tests validating CRLF preservation for item metadata when loading projects from disk and in read-only mode.

Comment thread src/Build.UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs Outdated
Comment thread src/Build/Xml/XmlReaderExtension.cs
@VolPlita

VolPlita commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@dotnet-policy-service agree company="Microsoft"

@VolPlita
VolPlita temporarily deployed to copilot-pat-pool July 3, 2026 15:55 — with GitHub Actions Inactive
@VolPlita
VolPlita temporarily deployed to copilot-pat-pool July 3, 2026 15:59 — with GitHub Actions Inactive

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

agentic threat detected
Threat detection flagged this output in warn mode. Manual review is REQUIRED before any follow-up automation.

Details

The threat detection results could not be parsed.

Review the workflow run logs for details.

Code Review — PR #14261

✅ 21/24 dimensions clean.

Dimension Severity Finding
Cross-Platform Correctness MODERATE [WindowsOnlyFact] is unneeded — XmlTextReader (Normalization=false) preserves \r\n on Linux too; use [Fact]
Design / Test Placement MODERATE These tests don't use the XmlReaderNoIXmlLineInfo wrapper that defines the class's scope; better placed in ItemEvaluation_Tests.cs or a new XmlReaderExtension_Tests.cs
Code Simplification NIT Split([Environment.NewLine], ...).Length.ShouldBe(5) is redundant — an exact ShouldBe(...) already guarantees the count

Design concern: test placement

XmlReaderWithoutLocation_Tests was built around one scenario: loading a project from an XmlReader that doesn't implement IXmlLineInfo. Neither new test uses the XmlReaderNoIXmlLineInfo wrapper, and loadProjectsReadOnly: true is orthogonal to "without location". Better homes would be src/Build.UnitTests/Evaluation/ItemEvaluation_Tests.cs (where metadata value semantics tests already live) or a new XmlReaderExtension_Tests.cs that explicitly targets the XmlReaderExtension behavior documented in the updated comment.


The comment update in XmlReaderExtension.cs is a clear improvement — it replaces the vague "Ignore loadAsReadOnly for now" placeholder with an accurate rationale and five cross-referenced issues. The tests themselves are correct and will catch real regressions; the findings above are structural improvements only.

Generated by Expert Code Review (on open) for #14261 · 1.8K AIC · ⊞ 30.3K

Comment thread src/Build.UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs Outdated
Comment thread src/Build.UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs Outdated
Comment thread src/Build.UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs Outdated
Comment thread src/Build.UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs Outdated
@VolPlita
VolPlita temporarily deployed to copilot-pat-pool July 3, 2026 15:59 — with GitHub Actions Inactive
@VolPlita
VolPlita force-pushed the fix-4083-newline-regression-tests branch from 3bdd057 to 1b4c931 Compare July 7, 2026 11:21

@OvesN OvesN left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good expansion of our test coverage. I only have a few minor comments.

Comment thread src/Build/Xml/XmlReaderExtension.cs Outdated
Comment thread src/Build.UnitTests/Construction/XmlReaderWithoutLocation_Tests.cs
@VolPlita
VolPlita force-pushed the fix-4083-newline-regression-tests branch from 1f09485 to d0f7e50 Compare July 7, 2026 15:47
@VolPlita
VolPlita enabled auto-merge (squash) July 7, 2026 15:48
WarperSan pushed a commit to WarperSan/ThunderPipe that referenced this pull request Sep 17, 2026
Updated
[Microsoft.Build.Utilities.Core](https://github.com/dotnet/msbuild) from
18.9.6 to 18.10.1.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.Build.Utilities.Core's
releases](https://github.com/dotnet/msbuild/releases)._

## 18.10.1

## What's Changed
* [vs16.11] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13103
* [vs17.12] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13796
* [vs17.8] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13902
* [vs17.11] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13903
* [vs17.12] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13909
* [vs17.12] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13986
* Add vs18.9 to merge-flow config; retire vs18.3 by @​JanProvaznik in
dotnet/msbuild#14214
* Bump labeler-cache-retention to use issue-labeler v2.1.0 by
@​jeffhandley in dotnet/msbuild#14171
* Bump main to 18.10.0 after vs18.9 snap by @​JanProvaznik in
dotnet/msbuild#14216
* Improve release skill: Phase 2 DARC rules, VMR backflow, deterministic
baseline by @​JanProvaznik in
dotnet/msbuild#14220
* Determinize release: hardcode OptProf baseline + Phase 3.2 baseline
resolver by @​JanProvaznik in
dotnet/msbuild#14222
* Serialize BuildRequestConfiguration.RequestedTargets to fix solution
metaproject MSB4057 in parallel builds by @​ViktorHofer in
dotnet/msbuild#14223
* [main] Update dependencies from nuget/nuget.client by
@​dotnet-maestro[bot] in dotnet/msbuild#14203
* Core support for AbsolutePath/FileInfo/DirectoryInfo and ITaskItem<T>
as task parameters by @​baronfel in
dotnet/msbuild#13971
* [main] Update dependencies from dotnet/roslyn by @​dotnet-maestro[bot]
in dotnet/msbuild#14206
* Fix existence cache kind poisoning by @​AlesProkop in
dotnet/msbuild#14249
* [main] Source code updates from dotnet/dotnet by @​dotnet-maestro[bot]
in dotnet/msbuild#14226
* Don't disable the MSBuild server for /mt builds when node reuse is off
by @​AR-May in dotnet/msbuild#14248
* Enhance expert reviewer guidelines with additional checks. by @​AR-May
in dotnet/msbuild#14255
* [main] Source code updates from dotnet/dotnet by @​dotnet-maestro[bot]
in dotnet/msbuild#14253
* [main] Update dependencies from dotnet/roslyn by @​dotnet-maestro[bot]
in dotnet/msbuild#14268
* [main] Update dependencies from nuget/nuget.client by
@​dotnet-maestro[bot] in dotnet/msbuild#14267
* Bump github/gh-aw-actions/setup from 0.81.6 to 0.82.2 by
@​dependabot[bot] in dotnet/msbuild#14266
* Avoid boxing the struct enumerator in
PropertyDictionary<T>.GetEnumerator() by @​nareshjo in
dotnet/msbuild#14272
* Refresh copy marker when implementation output changes by @​AlesProkop
in dotnet/msbuild#14231
* Send task-host build process environment as delta by @​OvesN in
dotnet/msbuild#14126
* Add regression coverage for metadata newline preservation by
@​VolPlita in dotnet/msbuild#14261
* Fix EmbedInBinlog items with relative paths from child projects by
@​huulinhnguyen-dev in dotnet/msbuild#13990
* Stop requiring VersionPrefix updates in servicing - insert prerelease
versions to VS by @​ViktorHofer in
dotnet/msbuild#14277
* Fix WriteLinesToFile rewriting unchanged file when custom encoding is
used by @​huulinhnguyen-dev in
dotnet/msbuild#14146
* Enable trim/AOT analyzers for Microsoft.Build and clean up annotations
by @​JeremyKuhne in dotnet/msbuild#14064
* [automated] Merge branch 'vs18.9' => 'main' by @​github-actions[bot]
in dotnet/msbuild#14291
* Fix MicroBuild plugin feed URL to use allowed pkgs.dev.azure.com
format by @​AlesProkop in dotnet/msbuild#14295
* Pass ExcludeRestorePackageImports during restore to avoid redundant
evaluations by @​ViktorHofer with @​Copilot in
dotnet/msbuild#14274
* [vs18.7] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13988
* Adopt Clever Test Selection (CTS) as parallel, non-blocking PR
pipeline by @​jankratochvilcz in
dotnet/msbuild#14212
* Harden exceptions when connecting to server by @​JanProvaznik in
dotnet/msbuild#14292
* Update MicrosoftBuildVersion in analyzer template by
@​github-actions[bot] in dotnet/msbuild#13886
* Fix MSBuild Server client dropping build result under WaitAny race
(#​14172) by @​JanProvaznik in
dotnet/msbuild#14251
* Partially revert #​13660: remove NuGet RestoreTask transient TaskHost
workaround by @​JanProvaznik in
dotnet/msbuild#14297
* Disable daily AI credits guardrail for Expert Code Review workflow by
@​JanProvaznik with @​Copilot in
dotnet/msbuild#14314
* Localized file check-in by OneLocBuild Task: Build definition ID 9434:
Build ID 14614733 by @​dotnet-bot in
dotnet/msbuild#14246
* Add opt-in partial (stop-after-pass) project evaluation by
@​ViktorHofer in dotnet/msbuild#14290
* Use partial evaluation for -getProperty/-getItem without a target by
@​ViktorHofer in dotnet/msbuild#14296
* [main] Source code updates from dotnet/dotnet by @​dotnet-maestro[bot]
in dotnet/msbuild#14324
* [main] Update dependencies from dotnet/roslyn by @​dotnet-maestro[bot]
in dotnet/msbuild#14333
* [main] Update dependencies from nuget/nuget.client by
@​dotnet-maestro[bot] in dotnet/msbuild#14330
* Bump github/gh-aw-actions/setup from 0.82.2 to 0.82.8 by
@​dependabot[bot] in dotnet/msbuild#14328
* Restrict partial evaluation to ProjectInstance by @​ViktorHofer in
dotnet/msbuild#14340
 ... (truncated)

Commits viewable in [compare
view](dotnet/msbuild@v18.9.6...v18.10.1).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Microsoft.Build.Utilities.Core&package-manager=nuget&previous-version=18.9.6&new-version=18.10.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
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.

Add regression test for: Newlines in metadata are \n instead of \r\n on Windows

3 participants