Skip to content

[patch] Strip every trailing separator when canonicalizing a path - #404

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/308-trim-every-trailing-separator
Oct 9, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/308-trim-every-trailing-separator

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #308

What was wrong

SemanticPath.MakeCanonical removed only one trailing directory separator, although its doc says "Removes trailing directory separators". As a result, /home/user/a// canonicalized to /home/user/a/. That didn't equal /home/user/a, and PathContainment.IsStrictlyInside saw a longer path followed by a separator, so IsChildOf reported the directory as inside itself.

Change (Semantics.Paths/SemanticPath.cs)

  • The single if is now a loop that trims separators until the path ends in a non-separator or is a root. It still stops at the root, so // canonicalizes to / and C:\\ to C:\.
  • PathContainment is unchanged. Containment is now correct without it because both sides are canonical. The issue suggested a change there as optional defense in depth, but it isn't needed to fix this bug, so I left it out.

Tests (PathContainmentTests)

  • RepeatedTrailingSeparators_CanonicalizeToTheSameDirectory, with 2 and 3 separators: the path canonicalizes to the plain spelling, equals it, and neither path is a child or parent of the other.
  • RootWithRepeatedTrailingSeparators_StaysTheRoot: the root followed by two more separators canonicalizes to the root and is not a child of it.
  • With the fix reverted, all three cases fail. With the fix, the full Semantics.Test suite passes: 1483 passed, 0 failed, 8 skipped. Semantics.Paths builds for every target framework with no warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Co2rZq6e7TjwF2FMUzNoXu


Generated by Claude Code

SemanticPath.MakeCanonical removed at most one trailing directory
separator, so "/home/user/a//" canonicalized to "/home/user/a/". That was
not equal to "/home/user/a", and IsChildOf reported it as a child of
itself. The trim now loops until the path ends in a non-separator or is a
root, so "//" and "C:\\" still canonicalize to the root.

Fixes #308

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

sonarqubecloud Bot commented Oct 8, 2026

Copy link
Copy Markdown

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.

Path canonicalization strips only one trailing separator: "/home/user/a//" stays "/home/user/a/" and IsChildOf("/home/user/a") returns true

2 participants