Skip to content
Merged
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
9 changes: 6 additions & 3 deletions FlyingSocks/Sources/Socket+Darwin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,15 @@ extension Socket {
static func makeAddressUnix(path: String) -> Darwin.sockaddr_un {
var addr = Darwin.sockaddr_un()
addr.sun_family = sa_family_t(AF_UNIX)
let pathCount = min(path.utf8.count, 104)
// Darwin <sys/un.h> declares `char sun_path[104]`; reserve the last byte
// for the NUL terminator that String(cString:) and unlink() read back.
let pathCount = min(path.utf8.count, 103)
let len = UInt8(MemoryLayout<UInt8>.size + MemoryLayout<sa_family_t>.size + pathCount + 1)
_ = withUnsafeMutablePointer(to: &addr.sun_path.0) { ptr in
withUnsafeMutablePointer(to: &addr.sun_path.0) { ptr in
path.withCString {
strncpy(ptr, $0, Int(len))
_ = strncpy(ptr, $0, pathCount)
}
ptr[pathCount] = 0
}
addr.sun_len = len
return addr
Expand Down
26 changes: 25 additions & 1 deletion FlyingSocks/Tests/SocketAddressTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,30 @@ struct SocketAddressTests {
)
}

#if canImport(Darwin)
@Test
func unixMaxLengthPath_IsCorrectlyDecodedFromStorage() throws {
let path = "/tmp/" + String(repeating: "x", count: 98)
let addr = sockaddr_un.unix(path: path)

#expect(Int(addr.sun_len) <= MemoryLayout<sockaddr_un>.size)
#expect(
try Socket.makeAddress(from: addr.makeStorage()) == .unix(path)
)
}

@Test
func unixOverlongPath_TruncatesWithoutOverflow() throws {
let path = "/tmp/" + String(repeating: "x", count: 99)
let addr = sockaddr_un.unix(path: path)

#expect(Int(addr.sun_len) <= MemoryLayout<sockaddr_un>.size)
#expect(
try Socket.makeAddress(from: addr.makeStorage()) == .unix(String(path.prefix(103)))
)
}
#endif

#if canImport(Glibc) || canImport(Musl) || canImport(Android)
@Test
func unixAbstractNamespace_IsCorrectlyDecodedFromStorage() throws {
Expand Down Expand Up @@ -268,7 +292,7 @@ struct SocketAddressTests {
func maximumPathLengthForUnixDomainSocket() {
var addrUn = sockaddr_un()
addrUn.sun_family = sa_family_t(AF_UNIX)
let maxPathLength = MemoryLayout<sockaddr_un>.size - MemoryLayout<sa_family_t>.size - 1
let maxPathLength = MemoryLayout.size(ofValue: addrUn.sun_path) - 1
let maxPath = String(repeating: "a", count: maxPathLength)
_ = maxPath.withCString { pathPtr in
memcpy(&addrUn.sun_path, pathPtr, maxPath.count + 1)
Expand Down
Loading