Skip to content

Commit 80f5030

Browse files
committed
Strip \\?\ prefix from path generated by resolveSymlink
This aligns the implementation of resolveSymlinks with that of Foundation.String._resolvingSymlinksInPath, which received this canonicalization fix in swiftlang/swift-foundation#639.
1 parent 79f5ae3 commit 80f5030

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

Sources/TSCBasic/PathShims.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,21 @@ import Foundation
2424
public func resolveSymlinks(_ path: AbsolutePath) throws -> AbsolutePath {
2525
#if os(Windows)
2626
let handle: HANDLE = path.pathString.withCString(encodedAs: UTF16.self) {
27-
CreateFileW($0, GENERIC_READ, DWORD(FILE_SHARE_READ), nil,
27+
CreateFileW($0, GENERIC_READ, DWORD(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), nil,
2828
DWORD(OPEN_EXISTING), DWORD(FILE_FLAG_BACKUP_SEMANTICS), nil)
2929
}
3030
if handle == INVALID_HANDLE_VALUE { return path }
3131
defer { CloseHandle(handle) }
3232

3333
let dwLength: DWORD =
34-
GetFinalPathNameByHandleW(handle, nil, 0, DWORD(FILE_NAME_NORMALIZED))
34+
GetFinalPathNameByHandleW(handle, nil, 0, DWORD(VOLUME_NAME_DOS))
3535
return try withUnsafeTemporaryAllocation(of: WCHAR.self, capacity: Int(dwLength)) {
3636
guard GetFinalPathNameByHandleW(handle, $0.baseAddress!, DWORD($0.count),
37-
DWORD(FILE_NAME_NORMALIZED)) == dwLength - 1 else {
37+
DWORD(VOLUME_NAME_DOS)) == dwLength - 1 else {
3838
throw FileSystemError(.unknownOSError, path)
3939
}
40-
let path = String(decodingCString: $0.baseAddress!, as: UTF16.self)
40+
// When using `VOLUME_NAME_DOS`, the returned path uses `\\?\`.
41+
let path = String(decodingCString: $0.baseAddress!.advanced(by: 4), as: UTF16.self)
4142
return try AbsolutePath(path)
4243
}
4344
#else

0 commit comments

Comments
 (0)