From 9d164965c9fe04f3485b6ee213507548cac403d0 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 17 Aug 2019 20:49:05 -0500 Subject: [PATCH 1/2] localtime: don't hard-fault on argument type errors; handle localtime(float) It turns out `mp_obj_int_get_checked` is not appropriate to call when the argument is not of int or long type--the "checked" refers to guarding against overflow/underflow, not type checking. For compatibility with CPython, handle float arguments. Closes: #2069 --- shared-bindings/time/__init__.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index f34cb9c466..420bedf1c9 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -236,7 +236,12 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { return rtc_get_time_source_time(); } - mp_int_t secs = mp_obj_int_get_checked(args[0]); + mp_obj_t arg = args[0]; + if(mp_obj_is_float(arg)) + arg = mp_obj_new_int_from_float(mp_obj_get_float(arg)); + + mp_int_t secs = mp_obj_get_int(arg); + if (secs < EPOCH1970_EPOCH2000_DIFF_SECS) mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t")); From f384d2dd8004e1becac6183243caef4b4bbedf56 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 18 Aug 2019 08:11:14 -0500 Subject: [PATCH 2/2] shared-bindings/time: style --- shared-bindings/time/__init__.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 420bedf1c9..2654de09aa 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -237,13 +237,15 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { } mp_obj_t arg = args[0]; - if(mp_obj_is_float(arg)) + if (mp_obj_is_float(arg)) { arg = mp_obj_new_int_from_float(mp_obj_get_float(arg)); + } mp_int_t secs = mp_obj_get_int(arg); - if (secs < EPOCH1970_EPOCH2000_DIFF_SECS) + if (secs < EPOCH1970_EPOCH2000_DIFF_SECS) { mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t")); + } timeutils_struct_time_t tm; timeutils_seconds_since_epoch_to_struct_time(secs, &tm); @@ -275,8 +277,9 @@ STATIC mp_obj_t time_mktime(mp_obj_t t) { mp_raise_TypeError(translate("function takes exactly 9 arguments")); } - if (mp_obj_get_int(elem[0]) < 2000) + if (mp_obj_get_int(elem[0]) < 2000) { mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t")); + } mp_uint_t secs = timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5]));