diff --git a/Foundation/NSJSONSerialization.swift b/Foundation/NSJSONSerialization.swift index 8e08b85918..36120e3cbf 100644 --- a/Foundation/NSJSONSerialization.swift +++ b/Foundation/NSJSONSerialization.swift @@ -716,22 +716,25 @@ private struct JSONReader { defer { intEndPointer.deallocate(capacity: 1) } let doubleEndPointer = UnsafeMutablePointer?>.allocate(capacity: 1) defer { doubleEndPointer.deallocate(capacity: 1) } - let intResult = strtol(startPointer, intEndPointer, 10) let intDistance = startPointer.distance(to: intEndPointer[0]!) let doubleResult = strtod(startPointer, doubleEndPointer) let doubleDistance = startPointer.distance(to: doubleEndPointer[0]!) - + guard intDistance > 0 || doubleDistance > 0 else { return nil } - + if intDistance == doubleDistance { return (intResult, intDistance) } guard doubleDistance > 0 else { return nil } + + if doubleResult == doubleResult.rounded() { + return (Int(doubleResult), doubleDistance) + } return (doubleResult, doubleDistance) } } diff --git a/TestFoundation/TestNSJSONSerialization.swift b/TestFoundation/TestNSJSONSerialization.swift index 33eadcb209..0e4e09fe9d 100644 --- a/TestFoundation/TestNSJSONSerialization.swift +++ b/TestFoundation/TestNSJSONSerialization.swift @@ -468,7 +468,7 @@ extension TestNSJSONSerialization { XCTAssertEqual(result?[1] as? Int, -1) XCTAssertEqual(result?[2] as? Double, 1.3) XCTAssertEqual(result?[3] as? Double, -1.3) - XCTAssertEqual(result?[4] as? Double, 1000) + XCTAssertEqual(result?[4] as? Int, 1000) XCTAssertEqual(result?[5] as? Double, 0.001) } } catch { @@ -871,6 +871,7 @@ extension TestNSJSONSerialization { ("test_jsonObjectToOutputStreamInsufficientBuffer", test_jsonObjectToOutputStreamInsufficientBuffer), ("test_booleanJSONObject", test_booleanJSONObject), ("test_serialize_dictionaryWithDecimal", test_serialize_dictionaryWithDecimal), + ("test_serializeDecimalNumberJSONObject", test_serializeDecimalNumberJSONObject), ] } @@ -1214,6 +1215,22 @@ extension TestNSJSONSerialization { XCTAssertTrue(JSONSerialization.isValidJSONObject([true])) } + func test_serializeDecimalNumberJSONObject() { + let decimalArray = "[12.1,10.0,0.0,0.0001,20,\(Int.max)]" + do { + let data = decimalArray.data(using: String.Encoding.utf8) + let result = try JSONSerialization.jsonObject(with: data!, options: []) as? [Any] + XCTAssertEqual(result?[0] as! Double, 12.1) + XCTAssertEqual(result?[1] as! Int, 10) + XCTAssertEqual(result?[2] as! Int, 0) + XCTAssertEqual(result?[3] as! Double, 0.0001) + XCTAssertEqual(result?[4] as! Int, 20) + XCTAssertEqual(result?[5] as! Int, Int.max) + } catch { + XCTFail("Failed during serialization") + } + } + fileprivate func createTestFile(_ path: String,_contents: Data) -> String? { let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString + "/" do {