@@ -300,6 +300,8 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co
300
300
return b ;
301
301
}
302
302
303
+ #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
304
+
303
305
void mp_obj_int_buffer_overflow_check (mp_obj_t self_in , size_t nbytes , bool is_signed )
304
306
{
305
307
if (is_signed ) {
@@ -329,7 +331,43 @@ void mp_obj_int_buffer_overflow_check(mp_obj_t self_in, size_t nbytes, bool is_s
329
331
}
330
332
}
331
333
332
- mp_raise_OverflowError_varg (translate ("value would overflow a %d byte buffer" ), nbytes );
334
+ mp_raise_OverflowError_varg (translate ("value must fit in %d byte(s)" ), nbytes );
335
+ }
336
+
337
+ #endif // MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
338
+
339
+ void mp_small_int_buffer_overflow_check (mp_int_t val , size_t nbytes , bool is_signed ) {
340
+ // Fast path for zero.
341
+ if (val == 0 ) return ;
342
+ if (!is_signed ) {
343
+ if (val >= 0 ) {
344
+ // Using signed constants here, not UINT8_MAX, etc. to avoid any unintended conversions.
345
+ if (val <= 0xff ) return ; // Small values fit in any number of nbytes.
346
+ if (nbytes == 2 && val <= 0xffff ) return ;
347
+ #if !defined(__LP64__ )
348
+ // 32-bit ints and pointers
349
+ if (nbytes >= 4 ) return ; // Any mp_int_t will fit.
350
+ #else
351
+ // 64-bit ints and pointers
352
+ if (nbytes == 4 && val <= 0xffffffff ) return ;
353
+ if (nbytes >= 8 ) return ; // Any mp_int_t will fit.
354
+ #endif
355
+ } // Negative, fall through to failure.
356
+ } else {
357
+ // signed
358
+ if (val >= INT8_MIN && val <= INT8_MAX ) return ; // Small values fit in any number of nbytes.
359
+ if (nbytes == 2 && val >= INT16_MIN && val <= INT16_MAX ) return ;
360
+ #if !defined(__LP64__ )
361
+ // 32-bit ints and pointers
362
+ if (nbytes >= 4 ) return ; // Any mp_int_t will fit.
363
+ #else
364
+ // 64-bit ints and pointers
365
+ if (nbytes == 4 && val >= INT32_MIN && val <= INT32_MAX ) return ;
366
+ if (nbytes >= 8 ) return ; // Any mp_int_t will fit.
367
+ #endif
368
+ } // Fall through to failure.
369
+
370
+ mp_raise_OverflowError_varg (translate ("value must fit in %d byte(s)" ), nbytes );
333
371
}
334
372
335
373
#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
@@ -467,15 +505,16 @@ STATIC mp_obj_t int_to_bytes(size_t n_args, const mp_obj_t *args) {
467
505
byte * data = (byte * )vstr .buf ;
468
506
memset (data , 0 , len );
469
507
470
- mp_obj_int_buffer_overflow_check (args [0 ], len , false);
471
-
472
508
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
473
509
if (!MP_OBJ_IS_SMALL_INT (args [0 ])) {
510
+ mp_obj_int_buffer_overflow_check (args [0 ], len , false);
474
511
mp_obj_int_to_bytes_impl (args [0 ], big_endian , len , data );
475
512
} else
476
513
#endif
477
514
{
478
515
mp_int_t val = MP_OBJ_SMALL_INT_VALUE (args [0 ]);
516
+ // Small int checking is separate, to be fast.
517
+ mp_small_int_buffer_overflow_check (val , len , false);
479
518
size_t l = MIN ((size_t )len , sizeof (val ));
480
519
mp_binary_set_int (l , big_endian , data + (big_endian ? (len - l ) : 0 ), val );
481
520
}
0 commit comments