diff options
author | Damien George <damien.p.george@gmail.com> | 2015-10-01 22:48:48 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2015-10-01 22:48:48 +0100 |
commit | e5635f4ab3d0fd00dd3951865fea82003205dae1 (patch) | |
tree | 9a1de95044325db1d35f071148358ca87c0ba239 /py | |
parent | 2065373f67b126edfc3e0f2519aaad0956902c14 (diff) | |
download | micropython-e5635f4ab3d0fd00dd3951865fea82003205dae1.tar.gz micropython-e5635f4ab3d0fd00dd3951865fea82003205dae1.zip |
py: Catch all cases of integer (big and small) division by zero.
Diffstat (limited to 'py')
-rw-r--r-- | py/compile.c | 4 | ||||
-rw-r--r-- | py/objint_mpz.c | 14 | ||||
-rw-r--r-- | py/runtime.c | 3 |
3 files changed, 20 insertions, 1 deletions
diff --git a/py/compile.c b/py/compile.c index e00af60ad6..797d7a95e1 100644 --- a/py/compile.c +++ b/py/compile.c @@ -293,7 +293,9 @@ STATIC mp_parse_node_t fold_constants(compiler_t *comp, mp_parse_node_t pn, mp_m // pass } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_PERCENT)) { // int%int - pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, mp_small_int_modulo(arg0, arg1)); + if (arg1 != 0) { + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, mp_small_int_modulo(arg0, arg1)); + } } else { assert(MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_SLASH)); // should be if (arg1 != 0) { diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 69a81d2c39..73469f30d3 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -193,6 +193,9 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { if (0) { #if MICROPY_PY_BUILTINS_FLOAT } else if (op == MP_BINARY_OP_TRUE_DIVIDE || op == MP_BINARY_OP_INPLACE_TRUE_DIVIDE) { + if (mpz_is_zero(zrhs)) { + goto zero_division_error; + } mp_float_t flhs = mpz_as_float(zlhs); mp_float_t frhs = mpz_as_float(zrhs); return mp_obj_new_float(flhs / frhs); @@ -216,6 +219,11 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { break; case MP_BINARY_OP_FLOOR_DIVIDE: case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: { + if (mpz_is_zero(zrhs)) { + zero_division_error: + nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, + "division by zero")); + } mpz_t rem; mpz_init_zero(&rem); mpz_divmod_inpl(&res->mpz, &rem, zlhs, zrhs); if (zlhs->neg != zrhs->neg) { @@ -229,6 +237,9 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { } case MP_BINARY_OP_MODULO: case MP_BINARY_OP_INPLACE_MODULO: { + if (mpz_is_zero(zrhs)) { + goto zero_division_error; + } mpz_t quo; mpz_init_zero(&quo); mpz_divmod_inpl(&quo, &res->mpz, zlhs, zrhs); mpz_deinit(&quo); @@ -274,6 +285,9 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { break; case MP_BINARY_OP_DIVMOD: { + if (mpz_is_zero(zrhs)) { + goto zero_division_error; + } mp_obj_int_t *quo = mp_obj_int_new_mpz(); mpz_divmod_inpl(&quo->mpz, &res->mpz, zlhs, zrhs); // Check signs and do Python style modulo diff --git a/py/runtime.c b/py/runtime.c index 69ac7549b2..98cde83e53 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -389,6 +389,9 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_MODULO: case MP_BINARY_OP_INPLACE_MODULO: { + if (rhs_val == 0) { + goto zero_division; + } lhs_val = mp_small_int_modulo(lhs_val, rhs_val); break; } |