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>
pull/9608/head
Damien George 2022-10-14 15:49:52 +11:00
rodzic 89b3207376
commit 815920c87f
3 zmienionych plików z 91 dodań i 0 usunięć

Wyświetl plik

@ -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);

Wyświetl plik

@ -0,0 +1,42 @@
try:
from utime import ticks_diff, ticks_add
except ImportError:
print("SKIP")
raise SystemExit
# Maximum value returned from ticks_add, ticks_ms, etc.
TICKS_MAX = ticks_add(0, -1)
# Maximum value returned from ticks_diff.
TICKS_INTERVAL_MAX = TICKS_MAX // 2
# Invariants:
# - ticks_diff(ticks_add(T, delta), T) == delta
# - ticks_diff(T, ticks_add(T, delta)) == -delta
# Check actual values of ticks_add.
print(ticks_add(20, 12))
print(ticks_add(20, -12))
# Check invariant.
print(ticks_diff(ticks_add(100, 123), 100))
print(ticks_diff(ticks_add(100, -123), 100))
print(ticks_diff(100, ticks_add(100, 123)))
print(ticks_diff(100, ticks_add(100, -123)))
# Check limits.
for T in (0, 10, TICKS_MAX):
for delta in (
-TICKS_INTERVAL_MAX - 1,
-TICKS_INTERVAL_MAX,
0,
TICKS_INTERVAL_MAX,
TICKS_INTERVAL_MAX + 1,
):
try:
print(ticks_diff(ticks_add(T, delta), T) == delta)
except OverflowError:
print("OverflowError")
try:
print(ticks_diff(T, ticks_add(T, delta)) == -delta)
except OverflowError:
print("OverflowError")

Wyświetl plik

@ -0,0 +1,36 @@
32
8
123
-123
-123
123
OverflowError
OverflowError
True
True
True
True
True
True
OverflowError
OverflowError
OverflowError
OverflowError
True
True
True
True
True
True
OverflowError
OverflowError
OverflowError
OverflowError
True
True
True
True
True
True
OverflowError
OverflowError