From 77218dd403b7407eb5a747b1a1745aadee17a35b Mon Sep 17 00:00:00 2001 From: Simon Evans Date: Mon, 8 Mar 2021 16:27:21 +0000 Subject: [PATCH] JSONDecoder: Check that a parsed float does not return infinity. - The behaviour of the floating point string parsing for Float and Double was changed to return +/-infinity instead of nil on overflow. (https://github.com/apple/swift/pull/34339) - Add an isFinite check to ensure that the result of a floating point conversion still fits in the type, matching current behaviour. --- Sources/Foundation/JSONDecoder.swift | 2 +- Tests/Foundation/Tests/TestJSONEncoder.swift | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Sources/Foundation/JSONDecoder.swift b/Sources/Foundation/JSONDecoder.swift index 503f27a337..6913494cb8 100644 --- a/Sources/Foundation/JSONDecoder.swift +++ b/Sources/Foundation/JSONDecoder.swift @@ -404,7 +404,7 @@ extension JSONDecoderImpl: Decoder { as type: T.Type) throws -> T { if case .number(let number) = value { - guard let floatingPoint = T(number) else { + guard let floatingPoint = T(number), floatingPoint.isFinite else { var path = self.codingPath if let additionalKey = additionalKey { path.append(additionalKey) diff --git a/Tests/Foundation/Tests/TestJSONEncoder.swift b/Tests/Foundation/Tests/TestJSONEncoder.swift index 03a389f33d..c7e61a9b6b 100644 --- a/Tests/Foundation/Tests/TestJSONEncoder.swift +++ b/Tests/Foundation/Tests/TestJSONEncoder.swift @@ -601,14 +601,23 @@ class TestJSONEncoder : XCTestCase { func test_codingOfFloat() { test_codingOf(value: Float(1.5), toAndFrom: "1.5") + + // Check value too large fails to decode. + XCTAssertThrowsError(try JSONDecoder().decode(Float.self, from: "1e100".data(using: .utf8)!)) } func test_codingOfDouble() { test_codingOf(value: Double(1.5), toAndFrom: "1.5") + + // Check value too large fails to decode. + XCTAssertThrowsError(try JSONDecoder().decode(Double.self, from: "100e323".data(using: .utf8)!)) } func test_codingOfDecimal() { test_codingOf(value: Decimal.pi, toAndFrom: "3.14159265358979323846264338327950288419") + + // Check value too large fails to decode. + XCTAssertThrowsError(try JSONDecoder().decode(Decimal.self, from: "100e200".data(using: .utf8)!)) } func test_codingOfString() {