Skip to content

[patch] Keep ".." segments that climb above the start in RelativeDirectoryPath.Normalize - #380

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/relative-normalize-parent-segments
Oct 6, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/relative-normalize-parent-segments

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #288

What changed

RelativeDirectoryPath.Normalize() used to resolve the path against a dummy root (/ or C:\) with Path.GetFullPath, then make it relative again. At the root, .. resolves to the root itself, so every .. that climbed above the starting point was dropped. For example, ../sibling became sibling, which names a different directory.

The segments are now resolved lexically:

  • . is dropped.
  • .. removes the previous segment when there is one that isn't itself ... Otherwise it is kept.
  • The result is joined with the platform separator. An empty result becomes ., which is what the old code returned.

Because no dummy root is involved, the result is the same on every OS. The System.Runtime.InteropServices import is gone, since it was only used to pick that root.

Input Before After
../sibling sibling ../sibling
a/../../b b ../b
../../x/y x/y ../../x/y
a/./b/../c a/c a/c

Tests

  • Normalize_WithOnlyDots_ResolvesCorrectly now checks for exactly ../folder. Before, it only checked that the result contained folder.
  • A new data-driven test, Normalize_KeepsParentSegmentsThatClimbAboveTheStart, covers the issue's table plus a/./b/../c and a/...
  • With the fix reverted, 4 of the new or tightened cases fail. With the fix, all 25 PathUtilityTests pass, and the whole Paths slice passes (186 passed, 2 skipped).
  • Semantics.Paths builds cleanly for every target (net8–10, netstandard2.0/2.1), and the local Sonar analyzer build (.sonarlint/sonar-local.props) is clean too.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MZE6sRR8wRTGhthCM8sL2M


Generated by Claude Code

…ctoryPath.Normalize

Normalize resolved the path against a dummy filesystem root, where a ".." at the
root resolves to the root itself, so "../sibling" became "sibling" and the path
named a different directory. Resolve the segments lexically instead: "." is
dropped, ".." pops the previous segment when there is one that is not itself
"..", and is kept otherwise.

Fixes #288

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01MZE6sRR8wRTGhthCM8sL2M
@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 9b99ee4 into main Oct 6, 2026
15 checks passed
@matt-edmondson
matt-edmondson deleted the fix/relative-normalize-parent-segments branch October 6, 2026 13:01
This was referenced Oct 6, 2026
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.

RelativeDirectoryPath.Normalize() drops leading "..": "../sibling" becomes "sibling", so the path points somewhere else

2 participants