STINNER Victor added the comment:
This issue is tricky, I will try to explain it.
To understand the bug, I wrote the following function:
static int
_PyByteArray_CheckConsistency(PyByteArrayObject *obj)
{
assert(obj != NULL);
assert(PyByteArray_Check(obj));
assert(Py_SIZE(obj) >= 0);
assert(obj->ob_bytes <= obj->ob_start);
assert((obj->ob_start - obj->ob_bytes) <= obj->ob_alloc);
assert((obj->ob_alloc - (obj->ob_start - obj->ob_bytes)) >= Py_SIZE(obj));
return 1;
}
In this issue, I'm concerned by bytearray_setslice_linear() with growth < 0.
There are two cases:
(A) lo == 0
(B) lo != 0.
(A) It's trivial to rollback the change: restore previous value of ob_start.
(Another option is to update the size, which should be the same if I understood
correctly.) You retrieve the original object.
Expected result:
>>> b=bytearray(b'1234567890')
>>> del b[:6]
>>> b
bytearray(b'7890')
Current behaviour on MemoryError
>>> b=bytearray(b'1234567890')
>>> del b[:6]
>>> b
bytearray(b'7890\x00\xfb\xfb\xfb\xfb\xfb')
With the patch:
>>> b=bytearray(b'1234567890')
>>> del b[:6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError
>>> b
bytearray(b'1234567890')
(B) You cannot restore removed bytes. Currently, you get an inconsistent
bytearray object because its content is updated but not its size.
No error:
>>> b=bytearray(b'1234567890')
>>> del b[3:6]
>>> b
bytearray(b'1237890')
Current behaviour on MemoryError:
>>> b=bytearray(b'1234567890')
>>> del b[3:6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError
>>> b
bytearray(b'1237890890')
With the patch:
>>> b=bytearray(b'1234567890')
>>> del b[3:6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError
>>> b
bytearray(b'1237890')
With the patch, the deletion succeeded even if you get a MemoryError. The
bytearray object is consistent. It's just that its buffer could be smaller (it
wastes memory).
Note: I used gdb to inject a MemoryError in PyByteArray_Resize().
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue19568>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com