Fix some cases where AbsolutePath::relative(to: AbsolutePath) would assert on Windows#534
Conversation
daveinglis
commented
Dec 9, 2025
- there where a couple case where relative(to:) would assert on windows when a path was long (>260) and when tailing slashes where not removed in some cases.
975683d to
df81ada
Compare
|
@swift-ci test |
|
This needs some more work/investigation, seeing some strange crashes in swiftPM that this is causing |
df81ada to
f520ce0
Compare
Sources/TSCBasic/Path.swift
Outdated
| if string.first?.isASCII ?? false, string.first?.isLetter ?? false, string.first?.isLowercase ?? false, | ||
| let path: String | ||
| let hasDrive: Bool | ||
| if string.first?.isASCII ?? false, string.first?.isLetter ?? false, |
There was a problem hiding this comment.
issue (possibly-blocking): Does not account for long path.
This does not take into account long path \\?\D:\<very long path>. Can we instead use Regex to determine if the passed string matches the desired conditions?
There was a problem hiding this comment.
I think that it not supporting that is fine. Foundation does go to some lengths to ensure that long paths are transparent to the user (it converts on the way in and out). Users generally would not type the NT path (and you cannot copy it from explorer as that transacts in Win32 paths and cmd would rely on DOS paths).
f520ce0 to
57aa889
Compare
0544198 to
925a63d
Compare
925a63d to
ed6da1c
Compare
…ssert - there where a couple case where relative(to:) would assert on windows when a path was long (>206), when tailing slashes where not removed in some cases and when paths where on different drives. - strip long path prefix in appending methods.
ed6da1c to
450f001
Compare
|
@swift-ci test |
|
@swift-ci test windows |
compnerd
left a comment
There was a problem hiding this comment.
I think that there is a small edge case that isn't being considered, but this seems good outside of that.
| // Check if this is a root directory (e.g., "C:\" or just "\") | ||
| // A root directory is either just "\" or "X:\" where X is a drive letter | ||
| let isRootDir = result.count == 1 || // Just "\" | ||
| (result.count == 3 && result.dropFirst().first == ":") // "X:\" |
There was a problem hiding this comment.
Hmm, not sure I fully understand, how does this not also mark 1:\ as a rooted directory where it is actually a file (ADS) path?