From f6d2528c6476254f10cee6d5e97b4cb4d2bf2b04 Mon Sep 17 00:00:00 2001 From: Amerigo Mancino Date: Tue, 8 Oct 2024 15:12:52 +0200 Subject: [PATCH 1/4] Fixed a problem that caused an error when decoding optional values in arrays. --- Sources/CBORCoding/CBORDecoder.swift | 22 +++++++++++++++---- Tests/CBORCodingTests/CBORDecoderTests.swift | 23 ++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/Sources/CBORCoding/CBORDecoder.swift b/Sources/CBORCoding/CBORDecoder.swift index 5609fb8..3a5e0c2 100644 --- a/Sources/CBORCoding/CBORDecoder.swift +++ b/Sources/CBORCoding/CBORDecoder.swift @@ -1020,7 +1020,7 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer { defer { decoder.codingPath.removeLast() } let value = container[currentIndex] - guard !(value is CBOR.Null) else { + guard !(value is CBOR.Null) || (value is CBOR.Null && isOptionalType(type)) else { throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: decoder.codingPath + [CBOR.CodingKey(index: currentIndex)], debugDescription: "Expected \(T.self) but found null instead.")) } @@ -1039,7 +1039,7 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer { defer { decoder.codingPath.removeLast() } let value = container[currentIndex] - guard !(value is CBOR.Null) else { + guard !(value is CBOR.Null) || (value is CBOR.Null && isOptionalType(type)) else { throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: decoder.codingPath + [CBOR.CodingKey(index: currentIndex)], debugDescription: "Expected \(T.self) but found null instead.")) } @@ -1058,7 +1058,7 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer { defer { decoder.codingPath.removeLast() } let value = container[currentIndex] - guard !(value is CBOR.Null) else { + guard !(value is CBOR.Null) || (value is CBOR.Null && isOptionalType(type)) else { throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: decoder.codingPath + [CBOR.CodingKey(index: currentIndex)], debugDescription: "Expected \(T.self) but found null instead.")) } @@ -1077,7 +1077,7 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer { defer { decoder.codingPath.removeLast() } let value = container[currentIndex] - guard !(value is CBOR.Null) else { + guard !(value is CBOR.Null) || (value is CBOR.Null && isOptionalType(type)) else { throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: decoder.codingPath + [CBOR.CodingKey(index: currentIndex)], debugDescription: "Expected \(T.self) but found null instead.")) } @@ -1088,6 +1088,20 @@ private struct __CBORUnkeyedDecodingContainer: UnkeyedDecodingContainer { } } +// MARK: - Optional Extension + +// Protocol to determine if type is optional +// https://stackoverflow.com/questions/32536420/determine-if-any-type-is-optional + +protocol OptionalProtocol {} +extension Optional: OptionalProtocol {} + +extension __CBORUnkeyedDecodingContainer { + private func isOptionalType(_ type: Any.Type) -> Bool { + return type is OptionalProtocol.Type + } +} + // MARK: - DecodingError Extension extension DecodingError { diff --git a/Tests/CBORCodingTests/CBORDecoderTests.swift b/Tests/CBORCodingTests/CBORDecoderTests.swift index 25a7634..8c14681 100644 --- a/Tests/CBORCodingTests/CBORDecoderTests.swift +++ b/Tests/CBORCodingTests/CBORDecoderTests.swift @@ -1192,6 +1192,29 @@ class CBORDecoderTests: XCTestCase { XCTAssertNoThrow(try CBORDecoder().decode(Test2.self, from: convertFromHexString("0xA2616101616202"))) } + + func testDecodingNilValuesInArray() throws { + let arrayWithNilValues: [UInt?] = [nil, nil] + let arrayWithNilCborData = try CBOREncoder().encode(arrayWithNilValues) + + XCTAssertNoThrow(try CBORDecoder().decode([UInt?].self, from: arrayWithNilCborData)) + } + + func testDecodingNilValuesInArray2() throws { + let arrayWithNilValues: [UInt?] = [nil, 2] + let arrayWithNilCborData = try CBOREncoder().encode(arrayWithNilValues) + + XCTAssertNoThrow(try CBORDecoder().decode([UInt?].self, from: arrayWithNilCborData)) + } + + func testDecodingNilValuesInArray3() throws { + let arrayWithNilValues: [UInt?] = [nil, 2] + let arrayWithNilCborData = try CBOREncoder().encode(arrayWithNilValues) + + let decodedValue = try CBORDecoder().decode([UInt?].self, from: arrayWithNilCborData) + + XCTAssertEqual(decodedValue, [nil, 2]) + } // MARK: Private Methods From a2e53c20400140cad062d9e8fca73b97bbd97349 Mon Sep 17 00:00:00 2001 From: Amerigo Mancino Date: Tue, 8 Oct 2024 15:17:30 +0200 Subject: [PATCH 2/4] Added myself as contributor as per the pull request rules. --- .github/CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CONTRIBUTORS.md b/.github/CONTRIBUTORS.md index 40111ad..ee901a0 100644 --- a/.github/CONTRIBUTORS.md +++ b/.github/CONTRIBUTORS.md @@ -6,6 +6,7 @@ I would like to give a special thanks to all of the people below who have contri - [Jos Kuijpers](https://github.com/joskuijpers) - [Dave Abrahams](https://github.com/dabrahams) +- [Amerigo Mancino](https://github.com/AmerigoM) ## I would like to join this list! How can I help the project? From fb3da56763937c79ae718004ff2b2dbd4a3cc94f Mon Sep 17 00:00:00 2001 From: Amerigo Mancino Date: Tue, 8 Oct 2024 15:22:34 +0200 Subject: [PATCH 3/4] Updated version in CBORCoding.podspec following semver guidelines. --- CBORCoding.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CBORCoding.podspec b/CBORCoding.podspec index 7d3be4b..246044e 100644 --- a/CBORCoding.podspec +++ b/CBORCoding.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "CBORCoding" - s.version = "1.4.0" + s.version = "1.4.1" s.summary = "A CBOR Encoder and Decoder" s.description = <<-DESC A lightweight framework containing a coder pair for encoding and decoding `Codable` conforming types to and from CBOR document format for iOS, macOS, tvOS, and watchOS. From 69b86354f336bf126e4b65795c337844648866da Mon Sep 17 00:00:00 2001 From: Daniele Ceglia Date: Fri, 18 Oct 2024 15:34:12 +0200 Subject: [PATCH 4/4] Added myself as contributor as per the pull request rules. --- .github/CONTRIBUTORS.md | 1 + Half | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/CONTRIBUTORS.md b/.github/CONTRIBUTORS.md index ee901a0..588d007 100644 --- a/.github/CONTRIBUTORS.md +++ b/.github/CONTRIBUTORS.md @@ -7,6 +7,7 @@ I would like to give a special thanks to all of the people below who have contri - [Jos Kuijpers](https://github.com/joskuijpers) - [Dave Abrahams](https://github.com/dabrahams) - [Amerigo Mancino](https://github.com/AmerigoM) +- [Daniele Ceglia - Electrolux Professional](https://github.com/DanieleCeglia-EPR) ## I would like to join this list! How can I help the project? diff --git a/Half b/Half index bb32fc7..14b1ab3 160000 --- a/Half +++ b/Half @@ -1 +1 @@ -Subproject commit bb32fc7a5d5cfcee01e5442b1381450b1fcd4803 +Subproject commit 14b1ab35ffdf62c999ef1016ec0f8e745a6feed5