Skip to content

Commit de9b536

Browse files
committed
py: Raise a ValueError if range() step is zero.
Following CPython. Otherwise one gets either an infinite loop (if code is optimised by the uPy compiler) or possibly a divide-by-zero CPU exception.
1 parent 546ef30 commit de9b536

2 files changed

Lines changed: 6 additions & 3 deletions

File tree

py/compile.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,8 +1444,9 @@ STATIC void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
14441444
pn_range_start = args[0];
14451445
pn_range_end = args[1];
14461446
pn_range_step = args[2];
1447-
// We need to know sign of step. This is possible only if it's constant
1448-
if (!MP_PARSE_NODE_IS_SMALL_INT(pn_range_step)) {
1447+
// the step must be a non-zero constant integer to do the optimisation
1448+
if (!MP_PARSE_NODE_IS_SMALL_INT(pn_range_step)
1449+
|| MP_PARSE_NODE_LEAF_SMALL_INT(pn_range_step) == 0) {
14491450
optimize = false;
14501451
}
14511452
}

py/objrange.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,10 @@ STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t
105105
o->start = mp_obj_get_int(args[0]);
106106
o->stop = mp_obj_get_int(args[1]);
107107
if (n_args == 3) {
108-
// TODO check step is non-zero
109108
o->step = mp_obj_get_int(args[2]);
109+
if (o->step == 0) {
110+
mp_raise_ValueError("zero step");
111+
}
110112
}
111113
}
112114

0 commit comments

Comments
 (0)