Closed
Description
Bug report
Found by @emmatyping.
Bug description:
This affects list_extend_{set,dict,dictitems}
, e.g.:
static int
list_extend_set(PyListObject *self, PySetObject *other)
{
Py_ssize_t m = Py_SIZE(self);
Py_ssize_t n = PySet_GET_SIZE(other);
if (list_resize(self, m + n) < 0) {
return -1;
}
/* populate the end of self with iterable's items */
Py_ssize_t setpos = 0;
Py_hash_t hash;
PyObject *key;
PyObject **dest = self->ob_item + m; // UB if 'self' is the empty list!
while (_PySet_NextEntryRef((PyObject *)other, &setpos, &key, &hash)) {
FT_ATOMIC_STORE_PTR_RELEASE(*dest, key);
dest++;
}
Py_SET_SIZE(self, m + n);
return 0;
}
If a list object is empty, ob->ob_items
will be NULL. In particular, list_resize
won't allocate and the size will be 0. However:
PyObject **dest = self->ob_item + m;
becomes equivalent to NULL + 0
which is UB. There is no runtime error for now because the loop that follows is not executed.
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response