@@ -988,17 +988,18 @@ extension JSONDecoderImpl: Decoder {
988988 static private func _slowpath_unwrapFixedWidthInteger< T: FixedWidthInteger > ( as type: T . Type , json5: Bool , numberBuffer: BufferView < UInt8 > , fullSource: BufferView < UInt8 > , digitBeginning: BufferViewIndex < UInt8 > , for codingPathNode: _CodingPathNode , _ additionalKey: ( some CodingKey ) ? ) throws -> T {
989989 // This is the slow path... If the fast path has failed. For example for "34.0" as an integer, we try to parse as either a Decimal or a Double and then convert back, losslessly.
990990 if let double = Double ( prevalidatedBuffer: numberBuffer) {
991+ // T.init(exactly:) guards against non-integer Double(s), but the parser may
992+ // have already transformed the non-integer "1.0000000000000001" into 1, etc.
993+ // Proper lossless behavior should be implemented by the parser.
994+ guard let value = T ( exactly: double) else {
995+ throw JSONError . numberIsNotRepresentableInSwift ( parsed: String ( decoding: numberBuffer, as: UTF8 . self) )
996+ }
997+
991998 // The distance between Double(s) is >=2 from ±2^53.
992999 // 2^53 may represent either 2^53 or 2^53+1 rounded toward zero.
9931000 // This code makes it so you don't get integer A from integer B.
9941001 // Proper lossless behavior should be implemented by the parser.
9951002 if double. magnitude < Double ( sign: . plus, exponent: Double . significandBitCount + 1 , significand: 1 ) {
996- // T.init(exactly:) guards against non-integer Double(s), but the parser may
997- // have already transformed the non-integer "1.0000000000000001" into 1, etc.
998- // Proper lossless behavior should be implemented by the parser.
999- guard let value = T ( exactly: double) else {
1000- throw JSONError . numberIsNotRepresentableInSwift ( parsed: String ( decoding: numberBuffer, as: UTF8 . self) )
1001- }
10021003 return value
10031004 }
10041005 }
0 commit comments