Skip to content

[SR-7119] Swift.Decodable doesn't work properly with big Int64 numbers on iOS 10 #4250

Open
@swift-ci

Description

@swift-ci
Previous ID SR-7119
Radar None
Original Reporter vincent (JIRA User)
Type Bug
Environment

iOS 10
Swift 4.0

Additional Detail from JIRA
Votes 2
Component/s Foundation
Labels Bug, Codable
Assignee None
Priority Medium

md5: 7519541942cc0ceab4b15571af866560

Issue Description:

The "Parsed JSON number <1000000000000000070> does not fit in Int64." error occurs when running the following code on iOS 10.

struct MyDecodable: Decodable {
    var id: Int64
}

let str = "{\"id\":1000000000000000070}"
let data = str.data(using: .utf8)!
let decodable = try! JSONDecoder().decode(MyDecodable.self, from: data)

It seems that on iOS 10, for some big numbers that fit in an Int64, JSONSerialization creates not a normal NSNumber but an instance of NSDecimalNumber.
On iOS 11, a big number like the one above becomes an NSNumber so everything works fine.

iOS 10 probably can't be fixed but it seems to me that changing the code at https://github.com/apple/swift/blob/a62647f0685c3c832756d9f635cfe527d45037de/stdlib/public/SDK/Foundation/JSONEncoder.swift#L2100-L2103 to the code below would fix the problem.

let int64 = number.int64Value
let recreatedNumber = number is NSDecimalNumber ? NSDecimalNumber(value: int64) : NSNumber(value: int64)
guard recreatedNumber == number else {
    throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions