Skip to content

Preserve whitespace-path throw in StaticWebAsset.NormalizeContentRootPath#54868

Open
jankratochvilcz wants to merge 2 commits into
dotnet:mainfrom
jankratochvilcz:swa-normalize-contentroot-whitespace-compat
Open

Preserve whitespace-path throw in StaticWebAsset.NormalizeContentRootPath#54868
jankratochvilcz wants to merge 2 commits into
dotnet:mainfrom
jankratochvilcz:swa-normalize-contentroot-whitespace-compat

Conversation

@jankratochvilcz

Copy link
Copy Markdown
Contributor

Follow-up to #54621.

Veronika (review comment) raised a backwards-compatibility concern about NormalizeContentRootPath(string path, TaskEnvironment env):

What if path is whitespace? It will return to us project dir and will not throw on getFullPath as it was before migration for whitespace input.

The regression

Before the multi-threaded migration, the raw path flowed straight into Path.GetFullPath. On Windows, Path.GetFullPath(" ") trims the trailing whitespace to an empty path and throws ArgumentException. After the migration the path was first routed through TaskEnvironment.GetAbsolutePath, which resolves it against the project directory — so an invalid whitespace OutputPath/ContentRoot was silently turned into the project directory instead of throwing.

The fix (backwards compatible)

Guard with string.IsNullOrWhiteSpace instead of string.IsNullOrEmpty:

=> Path.GetFullPath(string.IsNullOrWhiteSpace(path) ? path : env.GetAbsolutePath(path)) + ...

Whitespace-only inputs now bypass env.GetAbsolutePath and flow straight into Path.GetFullPath, exactly as before the migration:

  • Windows: throws ArgumentException (invalid path), as it did pre-migration.
  • Unix: whitespace is a legal path segment, so it resolves against the legacy base (process CWD), not silently against the project directory.

Valid relative paths are unaffected and still resolve against the project directory (MT-safe).

Test proving the mitigated behavior change

NormalizeContentRootPath_WithWhitespacePath_PreservesLegacyBehavior_DoesNotResolveAgainstProjectDirectory runs under a decoy CWD distinct from the project directory and asserts that a whitespace path is not re-rooted to the project directory (throws on Windows; resolves against the CWD on Unix). I verified the test fails against the previous IsNullOrEmpty implementation and passes with this fix.

Validation

  • ./.dotnet/dotnet build test/Microsoft.NET.Sdk.StaticWebAssets.Tests/Microsoft.NET.Sdk.StaticWebAssets.Tests.csproj -c Debug
  • Ran *NormalizeContentRootPath* (4 tests) — all pass; new test fails on the pre-fix code.

After the multi-threaded migration, NormalizeContentRootPath(path, env)
routed whitespace-only paths through TaskEnvironment.GetAbsolutePath,
which silently resolved them against the project directory. Previously
the raw path flowed into Path.GetFullPath, which on Windows trims
trailing whitespace to an empty path and throws ArgumentException.

Guard with string.IsNullOrWhiteSpace instead of string.IsNullOrEmpty so
whitespace-only inputs keep their pre-migration behavior (throwing on
Windows, resolving against the legacy base on Unix) instead of being
silently re-rooted to the project directory.

Adds a unit test demonstrating the mitigated behavior change.

Addresses review feedback on dotnet#54621.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 18, 2026 15:36

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 restores pre-multithreading/back-compat behavior for whitespace-only ContentRoot/OutputPath inputs in StaticWebAsset.NormalizeContentRootPath(string, TaskEnvironment) by ensuring whitespace bypasses TaskEnvironment.GetAbsolutePath and flows directly into Path.GetFullPath.

Changes:

  • Update NormalizeContentRootPath(string, TaskEnvironment) to use string.IsNullOrWhiteSpace when deciding whether to route through TaskEnvironment.GetAbsolutePath.
  • Add a cross-platform regression test that verifies whitespace-only paths are not silently re-rooted to the project directory (throwing on Windows; resolving against process CWD on Unix).

Reviewed changes

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

File Description
src/StaticWebAssetsSdk/Tasks/Data/StaticWebAsset.cs Preserves legacy whitespace-path behavior by bypassing TaskEnvironment.GetAbsolutePath for null/empty/whitespace inputs.
test/Microsoft.NET.Sdk.StaticWebAssets.Tests/StaticWebAssets/StaticWebAssetTaskEnvironmentTests.cs Adds a regression test validating whitespace-only path behavior remains consistent with the pre-migration semantics across OSes.

Comment on lines +1101 to +1105
// For null/empty/whitespace paths we deliberately call Path.GetFullPath on the raw value
// rather than routing it through env.GetAbsolutePath. This preserves the pre-multithreading
// behavior: such inputs resolve against the legacy base (and on Windows whitespace-only paths
// still throw, since Path.GetFullPath trims trailing whitespace to an empty path) instead of
// being silently resolved into the project directory.
Replace the single runtime-branched test with two focused tests gated by
[WindowsOnlyFact] and [LinuxOnlyFact], and shorten the comments.

Co-authored-by: Copilot <223556219+Copilot@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.

2 participants