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, {})
pull/3829/head
Jeff Epler 2018-03-25 16:05:32 -05:00 zatwierdzone przez Damien George
rodzic a1acbad27a
commit 05b13fd292
2 zmienionych plików z 28 dodań i 3 usunięć

Wyświetl plik

@ -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) { 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 // Verify input objects have expected type
assert(MP_OBJ_IS_TYPE(locals_dict, &mp_type_dict)); // MicroPython restriction, for now 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 // 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_t *bases_items;
mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items); mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items);
for (size_t i = 0; i < bases_len; i++) { 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]); mp_obj_type_t *t = MP_OBJ_TO_PTR(bases_items[i]);
// TODO: Verify with CPy, tested on function type // TODO: Verify with CPy, tested on function type
if (t->make_new == NULL) { if (t->make_new == NULL) {

Wyświetl plik

@ -11,3 +11,21 @@ try:
type(1, 2) type(1, 2)
except TypeError: except TypeError:
print('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')