Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/TSCBasic/FileSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ private struct LocalFileSystem: FileSystem {
let fsr: UnsafePointer<Int8> = cwdStr.fileSystemRepresentation
defer { fsr.deallocate() }

return try? AbsolutePath(String(cString: fsr))
return try? AbsolutePath(validating: String(cString: fsr))
#endif
}

Expand Down
32 changes: 25 additions & 7 deletions Sources/TSCBasic/Path.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public struct AbsolutePath: Hashable, Sendable {
}
defer { LocalFree(pwszResult) }

self.init(String(decodingCString: pwszResult, as: UTF16.self))
try self.init(validating: String(decodingCString: pwszResult, as: UTF16.self))
#else
try self.init(basePath, RelativePath(validating: str))
#endif
Expand Down Expand Up @@ -515,12 +515,29 @@ private struct WindowsPath: Path, Sendable {
}

init(string: String) {
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,
string.count > 1, string[string.index(string.startIndex, offsetBy: 1)] == ":"
{
self.string = "\(string.first!.uppercased())\(string.dropFirst(1))"
hasDrive = true
path = "\(string.first!.uppercased())\(string.dropFirst(1))"
} else {
self.string = string
hasDrive = false
path = string
}
var droppedTailing: Bool = false
// There seems to be many assumptions around paths and trailing '\'
var substring = path[path.startIndex..<path.endIndex]
while !substring.isEmpty && substring.utf8.last == UInt8(ascii: "\\") {
substring = substring.dropLast()
droppedTailing = true
}
// Don't use stripped substring is we only have <drive>: left
if hasDrive && substring.count == 2 && droppedTailing {
self.string = Self.repr(path) + "\\"
} else {
self.string = Self.repr(String(substring))
}
}

Expand All @@ -544,7 +561,7 @@ private struct WindowsPath: Path, Sendable {
self.init(string: ".")
} else {
let realpath: String = Self.repr(path)
// Treat a relative path as an invalid relative path...
// Treat an absolute path as an invalid relative path
if Self.isAbsolutePath(realpath) || realpath.first == "\\" {
throw PathValidationError.invalidRelativePath(path)
}
Expand All @@ -568,6 +585,7 @@ private struct WindowsPath: Path, Sendable {
_ = string.withCString(encodedAs: UTF16.self) { root in
name.withCString(encodedAs: UTF16.self) { path in
PathAllocCombine(root, path, ULONG(PATHCCH_ALLOW_LONG_PATHS.rawValue), &result)
_ = PathCchStripPrefix(result, wcslen(result))
}
}
defer { LocalFree(result) }
Expand All @@ -579,6 +597,7 @@ private struct WindowsPath: Path, Sendable {
_ = string.withCString(encodedAs: UTF16.self) { root in
relativePath.string.withCString(encodedAs: UTF16.self) { path in
PathAllocCombine(root, path, ULONG(PATHCCH_ALLOW_LONG_PATHS.rawValue), &result)
_ = PathCchStripPrefix(result, wcslen(result))
}
}
defer { LocalFree(result) }
Expand Down Expand Up @@ -965,8 +984,7 @@ extension AbsolutePath {
preconditionFailure("invalid relative path computed from \(pathString)")
}
}

assert(AbsolutePath(base, result) == self)
assert(AbsolutePath(base, result) == self, "\(AbsolutePath(base, result)) != \(self)")
return result
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/TSCBasic/PathShims.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public func resolveSymlinks(_ path: AbsolutePath) throws -> AbsolutePath {
} else {
pathBaseAddress = UnsafePointer($0.baseAddress!)
}
return try AbsolutePath(String(decodingCString: pathBaseAddress, as: UTF16.self))
return try AbsolutePath(validating: String(decodingCString: pathBaseAddress, as: UTF16.self))
}
#else
let pathStr = path.pathString
Expand Down
6 changes: 4 additions & 2 deletions Sources/TSCUtility/FSWatch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,9 @@ public final class RDCWatcher {
}

if !GetOverlappedResult(watch.hDirectory, &watch.overlapped, &dwBytesReturned, false) {
guard let path = try? AbsolutePath(validating: watch.path) else { continue }
queue.async {
delegate?.pathsDidReceiveEvent([AbsolutePath(watch.path)])
delegate?.pathsDidReceiveEvent([path])
}
return
}
Expand All @@ -272,7 +273,8 @@ public final class RDCWatcher {
String(utf16CodeUnitsNoCopy: &pNotify.pointee.FileName,
count: Int(pNotify.pointee.FileNameLength) / MemoryLayout<WCHAR>.stride,
freeWhenDone: false)
paths.append(AbsolutePath(file))
guard let path = try? AbsolutePath(validating: file) else { continue }
paths.append(path)

pNotify = (UnsafeMutableRawPointer(pNotify) + Int(pNotify.pointee.NextEntryOffset))
.assumingMemoryBound(to: FILE_NOTIFY_INFORMATION.self)
Expand Down