Skip to content

Commit babdefd

Browse files
authored
TSCBasic: adjust AbsolutePath(_:relativeTo:) on Windows (#320)
Normalise the path prior to concatenation and canonicalization. This enables the underlying API to properly perform this operation in a single step and fixes a few cases where we would incorrect form paths.
1 parent 3ddceee commit babdefd

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

Sources/TSCBasic/Path.swift

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,25 +76,28 @@ public struct AbsolutePath: Hashable {
7676
self.init(str)
7777
} else {
7878
#if os(Windows)
79-
var joined: PWSTR!
80-
_ = basePath._impl.string.withCString(encodedAs: UTF16.self) { base in
81-
str.withCString(encodedAs: UTF16.self) { path in
82-
PathAllocCombine(base, path, ULONG(PATHCCH_ALLOW_LONG_PATHS.rawValue), &joined)
83-
}
79+
assert(!basePath.pathString.isEmpty)
80+
guard !str.isEmpty else {
81+
self.init(basePath._impl)
82+
return
8483
}
85-
defer { LocalFree(joined) }
8684

87-
let buffer: UnsafePointer<Int8> =
88-
String(decodingCString: joined, as: UTF16.self).fileSystemRepresentation
89-
defer { buffer.deallocate() }
85+
let base: UnsafePointer<Int8> =
86+
basePath.pathString.fileSystemRepresentation
87+
defer { base.deallocate() }
88+
89+
let path: UnsafePointer<Int8> = str.fileSystemRepresentation
90+
defer { path.deallocate() }
9091

91-
var canonical: PWSTR!
92-
_ = String(cString: buffer).withCString(encodedAs: UTF16.self) {
93-
PathAllocCanonicalize($0, ULONG(PATHCCH_ALLOW_LONG_PATHS.rawValue), &canonical)
92+
var pwszResult: PWSTR!
93+
_ = String(cString: base).withCString(encodedAs: UTF16.self) { pwszBase in
94+
String(cString: path).withCString(encodedAs: UTF16.self) { pwszPath in
95+
PathAllocCombine(pwszBase, pwszPath, ULONG(PATHCCH_ALLOW_LONG_PATHS.rawValue), &pwszResult)
96+
}
9497
}
95-
defer { LocalFree(canonical) }
98+
defer { LocalFree(pwszResult) }
9699

97-
self.init(String(decodingCString: canonical, as: UTF16.self))
100+
self.init(String(decodingCString: pwszResult, as: UTF16.self))
98101
#else
99102
self.init(basePath, RelativePath(str))
100103
#endif

0 commit comments

Comments
 (0)