From 5c3617b9e9088ecd9b81b02095ba7b41d6766edc Mon Sep 17 00:00:00 2001 From: Finagolfin Date: Fri, 24 Nov 2023 18:59:06 +0530 Subject: [PATCH 1/4] Android: update pread/pwrite for nullability annotations in NDK 26 --- Sources/System/Internals/Syscalls.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/System/Internals/Syscalls.swift b/Sources/System/Internals/Syscalls.swift index 9fcb2f90..3d375a52 100644 --- a/Sources/System/Internals/Syscalls.swift +++ b/Sources/System/Internals/Syscalls.swift @@ -71,7 +71,7 @@ internal func system_pread( #if ENABLE_MOCKING if mockingEnabled { return _mockInt(fd, buf, nbyte, offset) } #endif - return pread(fd, buf, nbyte, offset) + return pread(fd, buf!, nbyte, offset) } // lseek @@ -101,7 +101,7 @@ internal func system_pwrite( #if ENABLE_MOCKING if mockingEnabled { return _mockInt(fd, buf, nbyte, offset) } #endif - return pwrite(fd, buf, nbyte, offset) + return pwrite(fd, buf!, nbyte, offset) } internal func system_dup(_ fd: Int32) -> Int32 { From c2e8f24c7c81c1842af8a556f7940abf96ec3a5f Mon Sep 17 00:00:00 2001 From: Guillaume Lessard Date: Thu, 4 Jan 2024 17:48:48 -0800 Subject: [PATCH 2/4] avoid passing null pointer to pread() or pwrite() --- Sources/System/Internals/Syscalls.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/System/Internals/Syscalls.swift b/Sources/System/Internals/Syscalls.swift index 3d375a52..d4549070 100644 --- a/Sources/System/Internals/Syscalls.swift +++ b/Sources/System/Internals/Syscalls.swift @@ -71,7 +71,7 @@ internal func system_pread( #if ENABLE_MOCKING if mockingEnabled { return _mockInt(fd, buf, nbyte, offset) } #endif - return pread(fd, buf!, nbyte, offset) + return buf.map({ pread(fd, $0, nbyte, offset) }) ?? 0 } // lseek @@ -101,7 +101,7 @@ internal func system_pwrite( #if ENABLE_MOCKING if mockingEnabled { return _mockInt(fd, buf, nbyte, offset) } #endif - return pwrite(fd, buf!, nbyte, offset) + return buf.map({ pwrite(fd, $0, nbyte, offset) }) ?? 0 } internal func system_dup(_ fd: Int32) -> Int32 { From 14597334dcdad2f0e669909882bddbb6f2762034 Mon Sep 17 00:00:00 2001 From: Guillaume Lessard Date: Fri, 5 Jan 2024 17:57:14 -0800 Subject: [PATCH 3/4] [test] test reading and writing empty, nil-based buffers --- Tests/SystemTests/FileOperationsTest.swift | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Tests/SystemTests/FileOperationsTest.swift b/Tests/SystemTests/FileOperationsTest.swift index 8062aedc..ca178ba5 100644 --- a/Tests/SystemTests/FileOperationsTest.swift +++ b/Tests/SystemTests/FileOperationsTest.swift @@ -86,6 +86,30 @@ final class FileOperationsTest: XCTestCase { for test in syscallTestCases { test.runAllTests() } } + func testWriteFromEmptyBuffer() throws { + let fd = try FileDescriptor.open(FilePath("/dev/null"), .writeOnly) + let written1 = try fd.write(toAbsoluteOffset: 0, .init(start: nil, count: 0)) + XCTAssertEqual(written1, 0) + + let pointer = UnsafeMutableRawPointer.allocate(byteCount: 8, alignment: 8) + defer { pointer.deallocate() } + let empty = UnsafeRawBufferPointer(start: pointer, count: 0) + let written2 = try fd.write(toAbsoluteOffset: 0, empty) + XCTAssertEqual(written2, 0) + } + + func testReadToEmptyBuffer() throws { + let fd = try FileDescriptor.open(FilePath("/dev/random"), .readOnly) + let read1 = try fd.read(fromAbsoluteOffset: 0, into: .init(start: nil, count: 0)) + XCTAssertEqual(read1, 0) + + let pointer = UnsafeMutableRawPointer.allocate(byteCount: 8, alignment: 8) + defer { pointer.deallocate() } + let empty = UnsafeMutableRawBufferPointer(start: pointer, count: 0) + let read2 = try fd.read(fromAbsoluteOffset: 0, into: empty) + XCTAssertEqual(read2, 0) + } + func testHelpers() { // TODO: Test writeAll, writeAll(toAbsoluteOffset), closeAfter } From 5ca37e7d3997b00e19d4a77d45db7830b18b6f56 Mon Sep 17 00:00:00 2001 From: Guillaume Lessard Date: Fri, 8 Mar 2024 12:58:48 -0800 Subject: [PATCH 4/4] Android: more targeted approach to unusual nullabilities --- Sources/System/Internals/Syscalls.swift | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Sources/System/Internals/Syscalls.swift b/Sources/System/Internals/Syscalls.swift index d4549070..236ee6cd 100644 --- a/Sources/System/Internals/Syscalls.swift +++ b/Sources/System/Internals/Syscalls.swift @@ -71,7 +71,15 @@ internal func system_pread( #if ENABLE_MOCKING if mockingEnabled { return _mockInt(fd, buf, nbyte, offset) } #endif - return buf.map({ pread(fd, $0, nbyte, offset) }) ?? 0 +#if os(Android) + var zero = UInt8.zero + return withUnsafeMutablePointer(to: &zero) { + // this pread has a non-nullable `buf` pointer + pread(fd, buf ?? UnsafeMutableRawPointer($0), nbyte, offset) + } +#else + return pread(fd, buf, nbyte, offset) +#endif } // lseek @@ -101,7 +109,15 @@ internal func system_pwrite( #if ENABLE_MOCKING if mockingEnabled { return _mockInt(fd, buf, nbyte, offset) } #endif - return buf.map({ pwrite(fd, $0, nbyte, offset) }) ?? 0 +#if os(Android) + var zero = UInt8.zero + return withUnsafeMutablePointer(to: &zero) { + // this pwrite has a non-nullable `buf` pointer + pwrite(fd, buf ?? UnsafeRawPointer($0), nbyte, offset) + } +#else + return pwrite(fd, buf, nbyte, offset) +#endif } internal func system_dup(_ fd: Int32) -> Int32 {