@@ -24,6 +24,24 @@ macro_rules! err {
2424 } ;
2525}
2626
27+ macro_rules! check_overflow {
28+ ( $overflowed: ident, $buf: ident, $idx: ident, $start_idx: ident, $end_index: ident) => {
29+ if $overflowed {
30+ #[ cfg( not( feature = "big-int-as-float" ) ) ]
31+ {
32+ err!( $idx, get!( $buf, $idx) )
33+ }
34+ #[ cfg( feature = "big-int-as-float" ) ]
35+ {
36+ return f64_from_parts_slow(
37+ unsafe { $buf. get_kinda_unchecked( $start_idx..$end_index) } ,
38+ $start_idx,
39+ ) ;
40+ }
41+ }
42+ } ;
43+ }
44+
2745#[ cfg_attr( not( feature = "no-inline" ) , inline) ]
2846#[ allow( clippy:: cast_possible_truncation) ]
2947fn multiply_as_u128 ( a : u64 , b : u64 ) -> ( u64 , u64 ) {
@@ -166,7 +184,7 @@ impl<'de> Deserializer<'de> {
166184 start_idx,
167185 )
168186 } else if unlikely ! ( digit_count >= 18 ) {
169- parse_large_integer ( start_idx, buf, negative)
187+ parse_large_integer ( start_idx, buf, negative, idx )
170188 } else if is_structural_or_whitespace ( get ! ( buf, idx) ) == 0 {
171189 err ! ( idx, get!( buf, idx) )
172190 } else {
@@ -182,7 +200,12 @@ impl<'de> Deserializer<'de> {
182200#[ cfg( not( feature = "128bit" ) ) ]
183201#[ cold]
184202#[ allow( clippy:: cast_possible_wrap) ]
185- fn parse_large_integer ( start_idx : usize , buf : & [ u8 ] , negative : bool ) -> Result < StaticNode > {
203+ fn parse_large_integer (
204+ start_idx : usize ,
205+ buf : & [ u8 ] ,
206+ negative : bool ,
207+ #[ allow( unused_variables) ] end_index : usize ,
208+ ) -> Result < StaticNode > {
186209 let mut idx = start_idx;
187210 if negative {
188211 idx += 1 ;
@@ -197,16 +220,12 @@ fn parse_large_integer(start_idx: usize, buf: &[u8], negative: bool) -> Result<S
197220 let digit = u64:: from ( get ! ( buf, idx) - b'0' ) ;
198221 {
199222 let ( res, overflowed) = 10_u64 . overflowing_mul ( num) ;
200- if overflowed {
201- err ! ( idx, get!( buf, idx) )
202- }
223+ check_overflow ! ( overflowed, buf, idx, start_idx, end_index) ;
203224 num = res;
204225 }
205226 {
206227 let ( res, overflowed) = num. overflowing_add ( digit) ;
207- if overflowed {
208- err ! ( idx, get!( buf, idx) )
209- }
228+ check_overflow ! ( overflowed, buf, idx, start_idx, end_index) ;
210229 num = res;
211230 }
212231 idx += 1 ;
@@ -224,7 +243,12 @@ fn parse_large_integer(start_idx: usize, buf: &[u8], negative: bool) -> Result<S
224243#[ cfg( feature = "128bit" ) ]
225244#[ cold]
226245#[ allow( clippy:: cast_possible_wrap) ]
227- fn parse_large_integer ( start_idx : usize , buf : & [ u8 ] , negative : bool ) -> Result < StaticNode > {
246+ fn parse_large_integer (
247+ start_idx : usize ,
248+ buf : & [ u8 ] ,
249+ negative : bool ,
250+ end_index : usize ,
251+ ) -> Result < StaticNode > {
228252 let mut idx = start_idx;
229253 if negative {
230254 idx += 1 ;
@@ -239,16 +263,12 @@ fn parse_large_integer(start_idx: usize, buf: &[u8], negative: bool) -> Result<S
239263 let digit = u128:: from ( get ! ( buf, idx) - b'0' ) ;
240264 {
241265 let ( res, overflowed) = 10_u128 . overflowing_mul ( num) ;
242- if overflowed {
243- err ! ( idx, get!( buf, idx) )
244- }
266+ check_overflow ! ( overflowed, buf, idx, start_idx, end_index) ;
245267 num = res;
246268 }
247269 {
248270 let ( res, overflowed) = num. overflowing_add ( digit) ;
249- if overflowed {
250- err ! ( idx, get!( buf, idx) )
251- }
271+ check_overflow ! ( overflowed, buf, idx, start_idx, end_index) ;
252272 num = res;
253273 }
254274 idx += 1 ;
@@ -542,4 +562,14 @@ mod test {
542562 assert_eq ! ( to_value_from_str( "-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000596916642387374" ) ?, Static ( F64 ( -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000596916642387374 ) ) ) ;
543563 Ok ( ( ) )
544564 }
565+
566+ #[ test]
567+ #[ cfg( feature = "big-int-as-float" ) ]
568+ fn huge_int ( ) -> Result < ( ) , crate :: Error > {
569+ assert_eq ! (
570+ to_value_from_str( "999999999999999999999999999999" ) ?,
571+ Static ( F64 ( 999999999999999999999999999999f64 ) )
572+ ) ;
573+ Ok ( ( ) )
574+ }
545575}
0 commit comments