summaryrefslogtreecommitdiff
path: root/extmod
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2022-10-14 15:49:52 +1100
committerDamien George <damien@micropython.org>2022-10-14 15:54:53 +1100
commit815920c87f9bda6b3fb7ec24686154210c9e8774 (patch)
tree15603a38d4ad5d3d3989076197b0f1ea535b28ce /extmod
parent89b320737652829edbab921e86d7ad3962d86d9e (diff)
extmod/utime_mphal: Make ticks_add check for overflow of delta.
Work done in collaboration with @jimmo. Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'extmod')
-rw-r--r--extmod/utime_mphal.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/extmod/utime_mphal.c b/extmod/utime_mphal.c
index 3d1cdfd82..cd91c9553 100644
--- a/extmod/utime_mphal.c
+++ b/extmod/utime_mphal.c
@@ -95,6 +95,19 @@ STATIC mp_obj_t time_ticks_add(mp_obj_t ticks_in, mp_obj_t delta_in) {
// we assume that first argument come from ticks_xx so is small int
mp_uint_t ticks = MP_OBJ_SMALL_INT_VALUE(ticks_in);
mp_uint_t delta = mp_obj_get_int(delta_in);
+
+ // Check that delta does not overflow the range that ticks_diff can handle.
+ // This ensures the following:
+ // - ticks_diff(ticks_add(T, delta), T) == delta
+ // - ticks_diff(T, ticks_add(T, delta)) == -delta
+ // The latter requires excluding delta=-TICKS_PERIOD/2.
+ //
+ // This unsigned comparison is equivalent to a signed comparison of:
+ // delta <= TICKS_PERIOD/2 || delta >= TICKS_PERIOD/2
+ if (delta + MICROPY_PY_UTIME_TICKS_PERIOD / 2 - 1 >= MICROPY_PY_UTIME_TICKS_PERIOD - 1) {
+ mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("ticks interval overflow"));
+ }
+
return MP_OBJ_NEW_SMALL_INT((ticks + delta) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
}
MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_add_obj, time_ticks_add);