Skip to content

Commit fa18bdd

Browse files
committed
Fix some cases where AbsolutePath::relative(to: AbsolutePath) would assert
- there where a couple case where relative(to:) would assert on windows when a path was long (>206) and when tailing slashes where not removed in some cases.
1 parent 84d81b7 commit fa18bdd

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

Sources/TSCBasic/Path.swift

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -515,13 +515,25 @@ private struct WindowsPath: Path, Sendable {
515515
}
516516

517517
init(string: String) {
518+
var path: String
518519
if string.first?.isASCII ?? false, string.first?.isLetter ?? false, string.first?.isLowercase ?? false,
519520
string.count > 1, string[string.index(string.startIndex, offsetBy: 1)] == ":"
520521
{
521-
self.string = "\(string.first!.uppercased())\(string.dropFirst(1))"
522+
path = "\(string.first!.uppercased())\(string.dropFirst(1))"
522523
} else {
523-
self.string = string
524+
path = string
524525
}
526+
// There seems to be many assumptions around paths and trailing '\'
527+
var substring = path[path.startIndex..<path.endIndex]
528+
while !substring.isEmpty && substring.utf8.last == UInt8(ascii: "\\") {
529+
substring = substring.dropLast()
530+
}
531+
if !substring.isEmpty && substring.last != ":" {
532+
// Drop the trailing '\', unless the string path only
533+
// has '\', and unless the slashes are right after the drive letter.
534+
path = String(substring)
535+
}
536+
self.string = path
525537
}
526538

527539
private static func repr(_ path: String) -> String {
@@ -568,6 +580,7 @@ private struct WindowsPath: Path, Sendable {
568580
_ = string.withCString(encodedAs: UTF16.self) { root in
569581
name.withCString(encodedAs: UTF16.self) { path in
570582
PathAllocCombine(root, path, ULONG(PATHCCH_ALLOW_LONG_PATHS.rawValue), &result)
583+
_ = PathCchStripPrefix(result, wcslen(result))
571584
}
572585
}
573586
defer { LocalFree(result) }
@@ -579,6 +592,7 @@ private struct WindowsPath: Path, Sendable {
579592
_ = string.withCString(encodedAs: UTF16.self) { root in
580593
relativePath.string.withCString(encodedAs: UTF16.self) { path in
581594
PathAllocCombine(root, path, ULONG(PATHCCH_ALLOW_LONG_PATHS.rawValue), &result)
595+
_ = PathCchStripPrefix(result, wcslen(result))
582596
}
583597
}
584598
defer { LocalFree(result) }
@@ -965,8 +979,7 @@ extension AbsolutePath {
965979
preconditionFailure("invalid relative path computed from \(pathString)")
966980
}
967981
}
968-
969-
assert(AbsolutePath(base, result) == self)
982+
assert(AbsolutePath(base, result) == self, "\(AbsolutePath(base, result)) != \(self)")
970983
return result
971984
}
972985

0 commit comments

Comments
 (0)