@@ -2225,11 +2225,40 @@ extension URL {
2225
2225
#if os(Windows)
2226
2226
// Convert any "\" to "/" before storing the URL parse info
2227
2227
var filePath = path. replacing ( . _backslash, with: . _slash)
2228
+ let isAbsolute : Bool
2229
+ var iter = filePath. utf8. makeIterator ( )
2230
+ if let driveLetter = iter. next ( ) , driveLetter. isAlpha,
2231
+ iter. next ( ) == . _colon,
2232
+ iter. next ( ) != . _slash {
2233
+ // Drive-relative path: use the current directory for the given drive letter
2234
+ // as the base URL, and remove the drive letter from the relative path.
2235
+ let relativePath = String ( Substring ( filePath. utf8. dropFirst ( 2 ) ) )
2236
+ let basePath : String ? = " \( Unicode . Scalar ( driveLetter) ) : " . withCString ( encodedAs: UTF16 . self) { pwszDriveLetter in
2237
+ let dwLength : DWORD = GetFullPathNameW ( pwszDriveLetter, 0 , nil , nil )
2238
+ guard dwLength > 0 else {
2239
+ return nil
2240
+ }
2241
+ return try ? withUnsafeTemporaryAllocation ( of: WCHAR . self, capacity: Int ( dwLength) ) {
2242
+ guard GetFullPathNameW ( pwszDriveLetter, DWORD ( $0. count) , $0. baseAddress, nil ) > 0 else {
2243
+ return nil
2244
+ }
2245
+ return String ( decodingCString: $0. baseAddress!, as: UTF16 . self)
2246
+ }
2247
+ }
2248
+ guard let basePath else {
2249
+ self . init ( filePath: relativePath, directoryHint: directoryHint, relativeTo: base)
2250
+ return
2251
+ }
2252
+ baseURL = URL ( filePath: basePath, directoryHint: . isDirectory)
2253
+ filePath = relativePath
2254
+ isAbsolute = false
2255
+ } else {
2256
+ isAbsolute = URL . isAbsolute ( standardizing: & filePath)
2257
+ }
2228
2258
#else
2229
2259
var filePath = path
2230
- #endif
2231
-
2232
2260
let isAbsolute = URL . isAbsolute ( standardizing: & filePath)
2261
+ #endif
2233
2262
2234
2263
#if !NO_FILESYSTEM
2235
2264
if !isAbsolute {
0 commit comments