From c7e4353ffd43860ac02867e4e9ffbcd4709d49ac Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Thu, 14 Nov 2024 10:04:22 +0000 Subject: [PATCH 01/11] Add ByteBuffer methods getValidatedString and readValidatedString --- Sources/NIOCore/ByteBuffer-aux.swift | 41 +++++++++++++++++++++++++ Tests/NIOCoreTests/ByteBufferTest.swift | 20 ++++++++++++ 2 files changed, 61 insertions(+) diff --git a/Sources/NIOCore/ByteBuffer-aux.swift b/Sources/NIOCore/ByteBuffer-aux.swift index 799b3f8511..e020076b38 100644 --- a/Sources/NIOCore/ByteBuffer-aux.swift +++ b/Sources/NIOCore/ByteBuffer-aux.swift @@ -264,6 +264,47 @@ extension ByteBuffer { return result } + /// Get the string at `index` from this `ByteBuffer` decoding using the UTF-8 encoding. Does not move the reader index. + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// This is an alternative to `ByteBuffer.getString(at:length:)` which ensures the returned string is valid UTF8 + /// + /// - Parameters: + /// - index: The starting index into `ByteBuffer` containing the string of interest. + /// - length: The number of bytes making up the string. + /// - Returns: A `String` value containing the UTF-8 decoded selected bytes from this `ByteBuffer` or `nil` if + /// the requested bytes are not readable. + @inlinable + @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) + public func getValidatedString(at index: Int, length: Int) -> String? { + guard let range = self.rangeWithinReadableBytes(index: index, length: length) else { + return nil + } + return self.withUnsafeReadableBytes { pointer in + assert(range.lowerBound >= 0 && (range.upperBound - range.lowerBound) <= pointer.count) + return String(validating: UnsafeRawBufferPointer(fastRebase: pointer[range]), as: Unicode.UTF8.self) + } + } + + /// Read `length` bytes off this `ByteBuffer`, decoding it as `String` using the UTF-8 encoding. Move the reader index + /// forward by `length`. + /// + /// This is an alternative to `ByteBuffer.readString(length:)` which ensures the returned string is valid UTF8. If the + /// string is not valid UTF8 then the reader index is not advanced. + /// + /// - Parameters: + /// - length: The number of bytes making up the string. + /// - Returns: A `String` value deserialized from this `ByteBuffer` or `nil` if there aren't at least `length` bytes readable. + @inlinable + @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) + public mutating func readValidatedString(length: Int) -> String? { + guard let result = self.getValidatedString(at: self.readerIndex, length: length) else { + return nil + } + self.moveReaderIndex(forwardBy: length) + return result + } + // MARK: Substring APIs /// Write `substring` into this `ByteBuffer` using UTF-8 encoding, moving the writer index forward appropriately. /// diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index 3826b7e1c4..9e8ea38023 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -1315,6 +1315,26 @@ class ByteBufferTest: XCTestCase { XCTAssertEqual("a", buf.readString(length: 1)) } + @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) + func testReadValidatedString() throws { + buf.clear() + let expected = "hello" + buf.writeString(expected) + let actual = buf.readValidatedString(length: expected.utf8.count) + XCTAssertEqual(expected, actual) + XCTAssertEqual("", buf.readValidatedString(length: 0)) + XCTAssertNil(buf.readValidatedString(length: 1)) + } + + @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) + func testReadInvalidString() throws { + buf.clear() + buf.writeBytes([UInt8](repeating: 255, count: 16)) + let actual = buf.readValidatedString(length: 16) + XCTAssertNil(actual) + XCTAssertEqual(buf.readableBytes, 16) + } + func testSetIntegerBeyondCapacity() throws { var buf = ByteBufferAllocator().buffer(capacity: 32) XCTAssertLessThan(buf.capacity, 200) From 1c15fd906fef42ab28b79cb1e8bc3494bf321196 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Thu, 14 Nov 2024 10:05:58 +0000 Subject: [PATCH 02/11] swift-format --- Sources/NIOCore/ByteBuffer-aux.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/NIOCore/ByteBuffer-aux.swift b/Sources/NIOCore/ByteBuffer-aux.swift index e020076b38..ff5830b585 100644 --- a/Sources/NIOCore/ByteBuffer-aux.swift +++ b/Sources/NIOCore/ByteBuffer-aux.swift @@ -289,7 +289,7 @@ extension ByteBuffer { /// Read `length` bytes off this `ByteBuffer`, decoding it as `String` using the UTF-8 encoding. Move the reader index /// forward by `length`. /// - /// This is an alternative to `ByteBuffer.readString(length:)` which ensures the returned string is valid UTF8. If the + /// This is an alternative to `ByteBuffer.readString(length:)` which ensures the returned string is valid UTF8. If the /// string is not valid UTF8 then the reader index is not advanced. /// /// - Parameters: From 6ac9150e6a9af07dd845e518ff3f81ca8bdad213 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Thu, 14 Nov 2024 10:49:42 +0000 Subject: [PATCH 03/11] Swift 6 only --- Sources/NIOCore/ByteBuffer-aux.swift | 86 +++++++++++++------------ Tests/NIOCoreTests/ByteBufferTest.swift | 12 ++-- 2 files changed, 51 insertions(+), 47 deletions(-) diff --git a/Sources/NIOCore/ByteBuffer-aux.swift b/Sources/NIOCore/ByteBuffer-aux.swift index ff5830b585..ffc81444cf 100644 --- a/Sources/NIOCore/ByteBuffer-aux.swift +++ b/Sources/NIOCore/ByteBuffer-aux.swift @@ -264,47 +264,6 @@ extension ByteBuffer { return result } - /// Get the string at `index` from this `ByteBuffer` decoding using the UTF-8 encoding. Does not move the reader index. - /// The selected bytes must be readable or else `nil` will be returned. - /// - /// This is an alternative to `ByteBuffer.getString(at:length:)` which ensures the returned string is valid UTF8 - /// - /// - Parameters: - /// - index: The starting index into `ByteBuffer` containing the string of interest. - /// - length: The number of bytes making up the string. - /// - Returns: A `String` value containing the UTF-8 decoded selected bytes from this `ByteBuffer` or `nil` if - /// the requested bytes are not readable. - @inlinable - @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) - public func getValidatedString(at index: Int, length: Int) -> String? { - guard let range = self.rangeWithinReadableBytes(index: index, length: length) else { - return nil - } - return self.withUnsafeReadableBytes { pointer in - assert(range.lowerBound >= 0 && (range.upperBound - range.lowerBound) <= pointer.count) - return String(validating: UnsafeRawBufferPointer(fastRebase: pointer[range]), as: Unicode.UTF8.self) - } - } - - /// Read `length` bytes off this `ByteBuffer`, decoding it as `String` using the UTF-8 encoding. Move the reader index - /// forward by `length`. - /// - /// This is an alternative to `ByteBuffer.readString(length:)` which ensures the returned string is valid UTF8. If the - /// string is not valid UTF8 then the reader index is not advanced. - /// - /// - Parameters: - /// - length: The number of bytes making up the string. - /// - Returns: A `String` value deserialized from this `ByteBuffer` or `nil` if there aren't at least `length` bytes readable. - @inlinable - @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) - public mutating func readValidatedString(length: Int) -> String? { - guard let result = self.getValidatedString(at: self.readerIndex, length: length) else { - return nil - } - self.moveReaderIndex(forwardBy: length) - return result - } - // MARK: Substring APIs /// Write `substring` into this `ByteBuffer` using UTF-8 encoding, moving the writer index forward appropriately. /// @@ -943,3 +902,48 @@ extension Optional where Wrapped == ByteBuffer { } } } + +#if compiler(>=6) +extension ByteBuffer { + /// Get the string at `index` from this `ByteBuffer` decoding using the UTF-8 encoding. Does not move the reader index. + /// The selected bytes must be readable or else `nil` will be returned. + /// + /// This is an alternative to `ByteBuffer.getString(at:length:)` which ensures the returned string is valid UTF8 + /// + /// - Parameters: + /// - index: The starting index into `ByteBuffer` containing the string of interest. + /// - length: The number of bytes making up the string. + /// - Returns: A `String` value containing the UTF-8 decoded selected bytes from this `ByteBuffer` or `nil` if + /// the requested bytes are not readable. + @inlinable + @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) + public func getUTF8ValidatedString(at index: Int, length: Int) -> String? { + guard let range = self.rangeWithinReadableBytes(index: index, length: length) else { + return nil + } + return self.withUnsafeReadableBytes { pointer in + assert(range.lowerBound >= 0 && (range.upperBound - range.lowerBound) <= pointer.count) + return String(validating: UnsafeRawBufferPointer(fastRebase: pointer[range]), as: Unicode.UTF8.self) + } + } + + /// Read `length` bytes off this `ByteBuffer`, decoding it as `String` using the UTF-8 encoding. Move the reader index + /// forward by `length`. + /// + /// This is an alternative to `ByteBuffer.readString(length:)` which ensures the returned string is valid UTF8. If the + /// string is not valid UTF8 then the reader index is not advanced. + /// + /// - Parameters: + /// - length: The number of bytes making up the string. + /// - Returns: A `String` value deserialized from this `ByteBuffer` or `nil` if there aren't at least `length` bytes readable. + @inlinable + @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) + public mutating func readUTF8ValidatedString(length: Int) -> String? { + guard let result = self.getUTF8ValidatedString(at: self.readerIndex, length: length) else { + return nil + } + self.moveReaderIndex(forwardBy: length) + return result + } +} +#endif // compiler(>=6) \ No newline at end of file diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index 9e8ea38023..cd05fedbc6 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -1316,21 +1316,21 @@ class ByteBufferTest: XCTestCase { } @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) - func testReadValidatedString() throws { + func testReadUTF8ValidatedString() throws { buf.clear() let expected = "hello" buf.writeString(expected) - let actual = buf.readValidatedString(length: expected.utf8.count) + let actual = buf.readUTF8ValidatedString(length: expected.utf8.count) XCTAssertEqual(expected, actual) - XCTAssertEqual("", buf.readValidatedString(length: 0)) - XCTAssertNil(buf.readValidatedString(length: 1)) + XCTAssertEqual("", buf.readUTF8ValidatedString(length: 0)) + XCTAssertNil(buf.readUTF8ValidatedString(length: 1)) } @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) - func testReadInvalidString() throws { + func testReadUTF8InvalidString() throws { buf.clear() buf.writeBytes([UInt8](repeating: 255, count: 16)) - let actual = buf.readValidatedString(length: 16) + let actual = buf.readUTF8ValidatedString(length: 16) XCTAssertNil(actual) XCTAssertEqual(buf.readableBytes, 16) } From e4a4d1fc0115c8f117bd76ecba507fd7b1c26d01 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Thu, 14 Nov 2024 10:53:50 +0000 Subject: [PATCH 04/11] swift-format --- Sources/NIOCore/ByteBuffer-aux.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/NIOCore/ByteBuffer-aux.swift b/Sources/NIOCore/ByteBuffer-aux.swift index ffc81444cf..d51e5c0de4 100644 --- a/Sources/NIOCore/ByteBuffer-aux.swift +++ b/Sources/NIOCore/ByteBuffer-aux.swift @@ -946,4 +946,4 @@ extension ByteBuffer { return result } } -#endif // compiler(>=6) \ No newline at end of file +#endif // compiler(>=6) From 712ee777ea3f4c385508aeeb91c4e7a156f60c44 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Thu, 14 Nov 2024 11:49:08 +0000 Subject: [PATCH 05/11] Throw error when string is not valid UTF8 --- Sources/NIOCore/ByteBuffer-aux.swift | 35 ++++++++++++++++++++----- Tests/NIOCoreTests/ByteBufferTest.swift | 16 +++++++---- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Sources/NIOCore/ByteBuffer-aux.swift b/Sources/NIOCore/ByteBuffer-aux.swift index d51e5c0de4..21afe6574d 100644 --- a/Sources/NIOCore/ByteBuffer-aux.swift +++ b/Sources/NIOCore/ByteBuffer-aux.swift @@ -908,7 +908,8 @@ extension ByteBuffer { /// Get the string at `index` from this `ByteBuffer` decoding using the UTF-8 encoding. Does not move the reader index. /// The selected bytes must be readable or else `nil` will be returned. /// - /// This is an alternative to `ByteBuffer.getString(at:length:)` which ensures the returned string is valid UTF8 + /// This is an alternative to `ByteBuffer.getString(at:length:)` which ensures the returned string is valid UTF8. If the + /// string is not valid UTF8 then a `ReadUTF8ValidationError` error is thrown. /// /// - Parameters: /// - index: The starting index into `ByteBuffer` containing the string of interest. @@ -917,13 +918,21 @@ extension ByteBuffer { /// the requested bytes are not readable. @inlinable @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) - public func getUTF8ValidatedString(at index: Int, length: Int) -> String? { + public func getUTF8ValidatedString(at index: Int, length: Int) throws -> String? { guard let range = self.rangeWithinReadableBytes(index: index, length: length) else { return nil } - return self.withUnsafeReadableBytes { pointer in + return try self.withUnsafeReadableBytes { pointer in assert(range.lowerBound >= 0 && (range.upperBound - range.lowerBound) <= pointer.count) - return String(validating: UnsafeRawBufferPointer(fastRebase: pointer[range]), as: Unicode.UTF8.self) + guard + let string = String( + validating: UnsafeRawBufferPointer(fastRebase: pointer[range]), + as: Unicode.UTF8.self + ) + else { + throw ReadUTF8ValidationError.invalidUTF8 + } + return string } } @@ -931,19 +940,31 @@ extension ByteBuffer { /// forward by `length`. /// /// This is an alternative to `ByteBuffer.readString(length:)` which ensures the returned string is valid UTF8. If the - /// string is not valid UTF8 then the reader index is not advanced. + /// string is not valid UTF8 then a `ReadUTF8ValidationError` error is thrown and the reader index is not advanced. /// /// - Parameters: /// - length: The number of bytes making up the string. /// - Returns: A `String` value deserialized from this `ByteBuffer` or `nil` if there aren't at least `length` bytes readable. @inlinable @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) - public mutating func readUTF8ValidatedString(length: Int) -> String? { - guard let result = self.getUTF8ValidatedString(at: self.readerIndex, length: length) else { + public mutating func readUTF8ValidatedString(length: Int) throws -> String? { + guard let result = try self.getUTF8ValidatedString(at: self.readerIndex, length: length) else { return nil } self.moveReaderIndex(forwardBy: length) return result } + + /// Errors thrown when calling `readUTF8ValidatedString` or `getUTF8ValidatedString`. + public struct ReadUTF8ValidationError: Error { + private enum BaseError: Hashable { + case invalidUTF8 + } + + private var baseError: BaseError + + /// The length of the bytes to copy was negative. + public static let invalidUTF8: ReadUTF8ValidationError = .init(baseError: .invalidUTF8) + } } #endif // compiler(>=6) diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index cd05fedbc6..348268bfc3 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -1320,18 +1320,24 @@ class ByteBufferTest: XCTestCase { buf.clear() let expected = "hello" buf.writeString(expected) - let actual = buf.readUTF8ValidatedString(length: expected.utf8.count) + let actual = try buf.readUTF8ValidatedString(length: expected.utf8.count) XCTAssertEqual(expected, actual) - XCTAssertEqual("", buf.readUTF8ValidatedString(length: 0)) - XCTAssertNil(buf.readUTF8ValidatedString(length: 1)) + XCTAssertEqual("", try buf.readUTF8ValidatedString(length: 0)) + XCTAssertNil(try buf.readUTF8ValidatedString(length: 1)) } @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) func testReadUTF8InvalidString() throws { buf.clear() buf.writeBytes([UInt8](repeating: 255, count: 16)) - let actual = buf.readUTF8ValidatedString(length: 16) - XCTAssertNil(actual) + XCTAssertThrowsError(try buf.readUTF8ValidatedString(length: 16)) { error in + switch error { + case is ByteBuffer.ReadUTF8ValidationError: + break + default: + XCTFail("Error: \(error)") + } + } XCTAssertEqual(buf.readableBytes, 16) } From 88d6b803436f6db7820c86b53a5ab5095cce70b4 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Fri, 15 Nov 2024 11:38:26 +0000 Subject: [PATCH 06/11] Make ReadUTF8ValidationError Equatable --- Sources/NIOCore/ByteBuffer-aux.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/NIOCore/ByteBuffer-aux.swift b/Sources/NIOCore/ByteBuffer-aux.swift index 21afe6574d..2eddb28b70 100644 --- a/Sources/NIOCore/ByteBuffer-aux.swift +++ b/Sources/NIOCore/ByteBuffer-aux.swift @@ -956,7 +956,7 @@ extension ByteBuffer { } /// Errors thrown when calling `readUTF8ValidatedString` or `getUTF8ValidatedString`. - public struct ReadUTF8ValidationError: Error { + public struct ReadUTF8ValidationError: Error, Equatable { private enum BaseError: Hashable { case invalidUTF8 } From 926b53ee4f336316fe331ab7344fc91b0d27235d Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Tue, 19 Nov 2024 13:27:21 +0000 Subject: [PATCH 07/11] Use slice, add test for getUTF8ValidatedString --- Sources/NIOCore/ByteBuffer-aux.swift | 7 +++---- Tests/NIOCoreTests/ByteBufferTest.swift | 9 +++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Sources/NIOCore/ByteBuffer-aux.swift b/Sources/NIOCore/ByteBuffer-aux.swift index 2eddb28b70..2f5a121d90 100644 --- a/Sources/NIOCore/ByteBuffer-aux.swift +++ b/Sources/NIOCore/ByteBuffer-aux.swift @@ -919,14 +919,13 @@ extension ByteBuffer { @inlinable @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) public func getUTF8ValidatedString(at index: Int, length: Int) throws -> String? { - guard let range = self.rangeWithinReadableBytes(index: index, length: length) else { + guard let slice = self.getSlice(at: index, length: length) else { return nil } - return try self.withUnsafeReadableBytes { pointer in - assert(range.lowerBound >= 0 && (range.upperBound - range.lowerBound) <= pointer.count) + return try slice.withUnsafeReadableBytes { pointer in guard let string = String( - validating: UnsafeRawBufferPointer(fastRebase: pointer[range]), + validating: pointer, as: Unicode.UTF8.self ) else { diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index 348268bfc3..af9c2b995d 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -1326,6 +1326,15 @@ class ByteBufferTest: XCTestCase { XCTAssertNil(try buf.readUTF8ValidatedString(length: 1)) } + @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) + func testGetUTF8ValidatedString() throws { + buf.clear() + let expected = "hello, goodbye" + buf.writeString(expected) + let actual = try buf.getUTF8ValidatedString(at: 7, length: 7) + XCTAssertEqual("goodbye", actual) + } + @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) func testReadUTF8InvalidString() throws { buf.clear() From 242baca9730ec6aba815c08ac247ce24e0f54703 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Thu, 21 Nov 2024 11:58:02 +0000 Subject: [PATCH 08/11] Use readableBytesView --- Sources/NIOCore/ByteBuffer-aux.swift | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Sources/NIOCore/ByteBuffer-aux.swift b/Sources/NIOCore/ByteBuffer-aux.swift index 2f5a121d90..b00d4fe9a5 100644 --- a/Sources/NIOCore/ByteBuffer-aux.swift +++ b/Sources/NIOCore/ByteBuffer-aux.swift @@ -922,17 +922,13 @@ extension ByteBuffer { guard let slice = self.getSlice(at: index, length: length) else { return nil } - return try slice.withUnsafeReadableBytes { pointer in - guard - let string = String( - validating: pointer, - as: Unicode.UTF8.self - ) - else { - throw ReadUTF8ValidationError.invalidUTF8 - } - return string + guard let string = String( + validating: slice.readableBytesView, + as: Unicode.UTF8.self + ) else { + throw ReadUTF8ValidationError.invalidUTF8 } + return string } /// Read `length` bytes off this `ByteBuffer`, decoding it as `String` using the UTF-8 encoding. Move the reader index From 75ba374098c9239dc78e61081f94c02aa034f2ae Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Thu, 21 Nov 2024 11:59:19 +0000 Subject: [PATCH 09/11] Swift format --- Sources/NIOCore/ByteBuffer-aux.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Sources/NIOCore/ByteBuffer-aux.swift b/Sources/NIOCore/ByteBuffer-aux.swift index b00d4fe9a5..5e07f4af2b 100644 --- a/Sources/NIOCore/ByteBuffer-aux.swift +++ b/Sources/NIOCore/ByteBuffer-aux.swift @@ -922,10 +922,12 @@ extension ByteBuffer { guard let slice = self.getSlice(at: index, length: length) else { return nil } - guard let string = String( - validating: slice.readableBytesView, - as: Unicode.UTF8.self - ) else { + guard + let string = String( + validating: slice.readableBytesView, + as: Unicode.UTF8.self + ) + else { throw ReadUTF8ValidationError.invalidUTF8 } return string From f6f757675eb08cf1f6e132f73cbb90863bf61497 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Thu, 21 Nov 2024 14:07:22 +0000 Subject: [PATCH 10/11] Only compile UTF8 validated string tests i with Swift 6 or later --- Tests/NIOCoreTests/ByteBufferTest.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index af9c2b995d..6a6d1d1e3b 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -1315,6 +1315,7 @@ class ByteBufferTest: XCTestCase { XCTAssertEqual("a", buf.readString(length: 1)) } + #if compiler(>=6) @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) func testReadUTF8ValidatedString() throws { buf.clear() @@ -1349,6 +1350,7 @@ class ByteBufferTest: XCTestCase { } XCTAssertEqual(buf.readableBytes, 16) } + #endif // compiler(>=6) func testSetIntegerBeyondCapacity() throws { var buf = ByteBufferAllocator().buffer(capacity: 32) From 4cf7b20b64f3bdf1655befb2338b33d0c75fb2ae Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Thu, 21 Nov 2024 17:26:55 +0000 Subject: [PATCH 11/11] Move compiler test inside test functions and throw XCTSkip --- Tests/NIOCoreTests/ByteBufferTest.swift | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index 6a6d1d1e3b..6be0ce37a6 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -1315,9 +1315,9 @@ class ByteBufferTest: XCTestCase { XCTAssertEqual("a", buf.readString(length: 1)) } - #if compiler(>=6) @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) func testReadUTF8ValidatedString() throws { + #if compiler(>=6) buf.clear() let expected = "hello" buf.writeString(expected) @@ -1325,19 +1325,27 @@ class ByteBufferTest: XCTestCase { XCTAssertEqual(expected, actual) XCTAssertEqual("", try buf.readUTF8ValidatedString(length: 0)) XCTAssertNil(try buf.readUTF8ValidatedString(length: 1)) + #else + throw XCTSkip("'readUTF8ValidatedString' is only available in Swift 6 and later") + #endif // compiler(>=6) } @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) func testGetUTF8ValidatedString() throws { + #if compiler(>=6) buf.clear() let expected = "hello, goodbye" buf.writeString(expected) let actual = try buf.getUTF8ValidatedString(at: 7, length: 7) XCTAssertEqual("goodbye", actual) + #else + throw XCTSkip("'getUTF8ValidatedString' is only available in Swift 6 and later") + #endif // compiler(>=6) } @available(macOS 15, iOS 18, tvOS 18, watchOS 11, *) func testReadUTF8InvalidString() throws { + #if compiler(>=6) buf.clear() buf.writeBytes([UInt8](repeating: 255, count: 16)) XCTAssertThrowsError(try buf.readUTF8ValidatedString(length: 16)) { error in @@ -1349,8 +1357,10 @@ class ByteBufferTest: XCTestCase { } } XCTAssertEqual(buf.readableBytes, 16) + #else + throw XCTSkip("'readUTF8ValidatedString' is only available in Swift 6 and later") + #endif // compiler(>=6) } - #endif // compiler(>=6) func testSetIntegerBeyondCapacity() throws { var buf = ByteBufferAllocator().buffer(capacity: 32)