@@ -507,7 +507,25 @@ private struct WindowsPath: Path, Sendable {
507507 let normalized : UnsafePointer < Int8 > = string. fileSystemRepresentation
508508 defer { normalized. deallocate ( ) }
509509
510- return String ( cString: normalized) . components ( separatedBy: " \\ " ) . filter { !$0. isEmpty }
510+ var str = String ( cString: normalized)
511+ // Normalize extended-length prefixes before classifying.
512+ // \\?\UNC\server\share\... is a UNC path; \\?\C:\... is a local NT path.
513+ if str. hasPrefix ( #"\\?\UNC\"# ) {
514+ str = #"\\"# + str. dropFirst ( 7 ) // \\?\UNC\server → \\server
515+ } else if str. hasPrefix ( #"\\?\"# ) {
516+ str = String ( str. dropFirst ( 4 ) ) // \\?\C:\... → C:\...
517+ }
518+ // UNC paths (\\server\share\...) start with two backslashes. Preserve
519+ // that as a synthetic "UNC" first component so that paths on different
520+ // UNC servers/shares are never treated as descendants of each other, and
521+ // so that UNC paths are never confused with local absolute paths that
522+ // happen to share the same directory names. "UNC" is a plain string
523+ // with no backslashes, so it survives uses like lock-file name generation
524+ // that join components with a separator character.
525+ if str. hasPrefix ( " \\ \\ " ) {
526+ return [ " UNC " ] + str. dropFirst ( 2 ) . components ( separatedBy: " \\ " ) . filter { !$0. isEmpty }
527+ }
528+ return str. components ( separatedBy: " \\ " ) . filter { !$0. isEmpty }
511529 }
512530
513531 var parentDirectory : Self {
@@ -580,10 +598,11 @@ private struct WindowsPath: Path, Sendable {
580598
581599 func appending( component name: String ) -> Self {
582600 var result : PWSTR ?
583- _ = string. withCString ( encodedAs: UTF16 . self) { root in
601+ string. withCString ( encodedAs: UTF16 . self) { root in
584602 name. withCString ( encodedAs: UTF16 . self) { path in
585603 PathAllocCombine ( root, path, ULONG ( PATHCCH_ALLOW_LONG_PATHS . rawValue) , & result)
586- _ = PathCchStripPrefix ( result, wcslen ( result) )
604+ // PathCchStripPrefix's cchPath must include the null terminator.
605+ _ = PathCchStripPrefix ( result, wcslen ( result) + 1 )
587606 }
588607 }
589608 defer { LocalFree ( result) }
@@ -592,10 +611,11 @@ private struct WindowsPath: Path, Sendable {
592611
593612 func appending( relativePath: Self ) -> Self {
594613 var result : PWSTR ?
595- _ = string. withCString ( encodedAs: UTF16 . self) { root in
614+ string. withCString ( encodedAs: UTF16 . self) { root in
596615 relativePath. string. withCString ( encodedAs: UTF16 . self) { path in
597616 PathAllocCombine ( root, path, ULONG ( PATHCCH_ALLOW_LONG_PATHS . rawValue) , & result)
598- _ = PathCchStripPrefix ( result, wcslen ( result) )
617+ // PathCchStripPrefix's cchPath must include the null terminator.
618+ _ = PathCchStripPrefix ( result, wcslen ( result) + 1 )
599619 }
600620 }
601621 defer { LocalFree ( result) }
0 commit comments