From 05b13fd292b42f20affc7cae218d92447efbf6d6 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 25 Mar 2018 16:05:32 -0500 Subject: [PATCH] py/objtype: Fix assertion failures in mp_obj_new_type by checking types. Fixes assertion failures when the arguments to type() were not of valid types, e.g., when making calls like: type("", (), 3) type("", 3, {}) --- py/objtype.c | 13 ++++++++++--- tests/basics/builtin_type.py | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/py/objtype.c b/py/objtype.c index 2ec27c762c..9b57a50517 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -1005,8 +1005,13 @@ const mp_obj_type_t mp_type_type = { }; mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) { - assert(MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)); // MicroPython restriction, for now - assert(MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)); // MicroPython restriction, for now + // Verify input objects have expected type + if (!MP_OBJ_IS_TYPE(bases_tuple, &mp_type_tuple)) { + mp_raise_TypeError(NULL); + } + if (!MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)) { + mp_raise_TypeError(NULL); + } // TODO might need to make a copy of locals_dict; at least that's how CPython does it @@ -1015,7 +1020,9 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) mp_obj_t *bases_items; mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items); for (size_t i = 0; i < bases_len; i++) { - assert(MP_OBJ_IS_TYPE(bases_items[i], &mp_type_type)); + if (!MP_OBJ_IS_TYPE(bases_items[i], &mp_type_type)) { + mp_raise_TypeError(NULL); + } mp_obj_type_t *t = MP_OBJ_TO_PTR(bases_items[i]); // TODO: Verify with CPy, tested on function type if (t->make_new == NULL) { diff --git a/tests/basics/builtin_type.py b/tests/basics/builtin_type.py index 83c45c64b9..c5fb36626c 100644 --- a/tests/basics/builtin_type.py +++ b/tests/basics/builtin_type.py @@ -11,3 +11,21 @@ try: type(1, 2) except TypeError: print('TypeError') + +# second arg should be a tuple +try: + type('abc', None, None) +except TypeError: + print('TypeError') + +# third arg should be a dict +try: + type('abc', (), None) +except TypeError: + print('TypeError') + +# elements of second arg (the bases) should be types +try: + type('abc', (1,), {}) +except TypeError: + print('TypeError')