Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

[DonoT review] Removing rootlength variable from removeRelative segments #24273

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/System.Private.CoreLib/shared/System/IO/Path.Unix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static string GetFullPath(string path)

// We would ideally use realpath to do this, but it resolves symlinks, requires that the file actually exist,
// and turns it into a full path, which we only want if fullCheck is true.
string collapsedString = PathInternal.RemoveRelativeSegments(path, PathInternal.GetRootLength(path));
string collapsedString = PathInternal.RemoveRelativeSegments(path);

Debug.Assert(collapsedString.Length < path.Length || collapsedString.ToString() == path,
"Either we've removed characters, or the string should be unmodified from the input path.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public static string GetFullPath(string path, string basePath)
// them properly. As such we need to manually remove segments and not use GetFullPath().

return PathInternal.IsDevice(combinedPath.AsSpan())
? PathInternal.RemoveRelativeSegments(combinedPath, PathInternal.GetRootLength(combinedPath.AsSpan()))
? PathInternal.RemoveRelativeSegments(combinedPath)
: GetFullPath(combinedPath);
}

Expand Down
7 changes: 3 additions & 4 deletions src/System.Private.CoreLib/shared/System/IO/PathInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,11 @@ internal static bool AreRootsEqual(string first, string second, StringComparison
/// Try to remove relative segments from the given path (without combining with a root).
/// </summary>
/// <param name="path">Input path</param>
/// <param name="rootLength">The length of the root of the given path</param>
internal static string RemoveRelativeSegments(string path, int rootLength)
internal static string RemoveRelativeSegments(string path)
{
Span<char> initialBuffer = stackalloc char[260 /* PathInternal.MaxShortPath */];
ValueStringBuilder sb = new ValueStringBuilder(initialBuffer);
int rootLength = GetRootLength(path.AsSpan());

if (RemoveRelativeSegments(path.AsSpan(), rootLength, ref sb))
{
Expand All @@ -139,14 +139,13 @@ internal static string RemoveRelativeSegments(string path, int rootLength)
/// <returns>"true" if the path was modified</returns>
internal static bool RemoveRelativeSegments(ReadOnlySpan<char> path, int rootLength, ref ValueStringBuilder sb)
{
Debug.Assert(rootLength > 0);
bool flippedSeparator = false;

int skip = rootLength;
// We treat "\.." , "\." and "\\" as a relative segment. We want to collapse the first separator past the root presuming
// the root actually ends in a separator. Otherwise the first segment for RemoveRelativeSegments
// in cases like "\\?\C:\.\" and "\\?\C:\..\", the first segment after the root will be ".\" and "..\" which is not considered as a relative segment and hence not be removed.
if (PathInternal.IsDirectorySeparator(path[skip - 1]))
if (skip > 0 && PathInternal.IsDirectorySeparator(path[skip - 1]))
skip--;

// Remove "//", "/./", and "/../" from the path by copying each character to the output,
Expand Down