Skip to content

Commit eb8fa91

Browse files
“saiHemak”root
authored andcommitted
Fix for [SR-1250] NSJSONSerialization emits non-floating-point numbers as Double
1 parent a30b185 commit eb8fa91

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

Foundation/NSJSONSerialization.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -716,22 +716,25 @@ private struct JSONReader {
716716
defer { intEndPointer.deallocate(capacity: 1) }
717717
let doubleEndPointer = UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>.allocate(capacity: 1)
718718
defer { doubleEndPointer.deallocate(capacity: 1) }
719-
720719
let intResult = strtol(startPointer, intEndPointer, 10)
721720
let intDistance = startPointer.distance(to: intEndPointer[0]!)
722721
let doubleResult = strtod(startPointer, doubleEndPointer)
723722
let doubleDistance = startPointer.distance(to: doubleEndPointer[0]!)
724-
723+
725724
guard intDistance > 0 || doubleDistance > 0 else {
726725
return nil
727726
}
728-
727+
729728
if intDistance == doubleDistance {
730729
return (intResult, intDistance)
731730
}
732731
guard doubleDistance > 0 else {
733732
return nil
734733
}
734+
735+
if doubleResult == doubleResult.rounded() {
736+
return (Int(doubleResult), doubleDistance)
737+
}
735738
return (doubleResult, doubleDistance)
736739
}
737740
}

TestFoundation/TestNSJSONSerialization.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ extension TestNSJSONSerialization {
468468
XCTAssertEqual(result?[1] as? Int, -1)
469469
XCTAssertEqual(result?[2] as? Double, 1.3)
470470
XCTAssertEqual(result?[3] as? Double, -1.3)
471-
XCTAssertEqual(result?[4] as? Double, 1000)
471+
XCTAssertEqual(result?[4] as? Int, 1000)
472472
XCTAssertEqual(result?[5] as? Double, 0.001)
473473
}
474474
} catch {
@@ -871,6 +871,7 @@ extension TestNSJSONSerialization {
871871
("test_jsonObjectToOutputStreamInsufficientBuffer", test_jsonObjectToOutputStreamInsufficientBuffer),
872872
("test_booleanJSONObject", test_booleanJSONObject),
873873
("test_serialize_dictionaryWithDecimal", test_serialize_dictionaryWithDecimal),
874+
("test_serializeDecimalNumberJSONObject", test_serializeDecimalNumberJSONObject),
874875
]
875876
}
876877

@@ -1214,6 +1215,22 @@ extension TestNSJSONSerialization {
12141215
XCTAssertTrue(JSONSerialization.isValidJSONObject([true]))
12151216
}
12161217

1218+
func test_serializeDecimalNumberJSONObject() {
1219+
let decimalArray = "[12.1,10.0,0.0,0.0001,20,\(Int.max)]"
1220+
do {
1221+
let data = decimalArray.data(using: String.Encoding.utf8)
1222+
let result = try JSONSerialization.jsonObject(with: data!, options: []) as? [Any]
1223+
XCTAssertEqual(result?[0] as! Double, 12.1)
1224+
XCTAssertEqual(result?[1] as! Int, 10)
1225+
XCTAssertEqual(result?[2] as! Int, 0)
1226+
XCTAssertEqual(result?[3] as! Double, 0.0001)
1227+
XCTAssertEqual(result?[4] as! Int, 20)
1228+
XCTAssertEqual(result?[5] as! Int, Int.max)
1229+
} catch {
1230+
XCTFail("Failed during serialization")
1231+
}
1232+
}
1233+
12171234
fileprivate func createTestFile(_ path: String,_contents: Data) -> String? {
12181235
let tempDir = NSTemporaryDirectory() + "TestFoundation_Playground_" + NSUUID().uuidString + "/"
12191236
do {

0 commit comments

Comments
 (0)