While testing injection of memory allocation failures in the _bz2 extension module, I found a bug: PyBytesWriter_Discard() is called twice on a memory allocation failure.
Example:
import _testcapi
import bz2
data = bz2.compress(b'x' * 1024)
decompressor = bz2.BZ2Decompressor()
try:
_testcapi.set_nomemory(3,4)
try:
decompressor.decompress(data)
except MemoryError:
pass
else:
raise Exception
finally:
_testcapi.remove_mem_hooks()
print("exit")
The error occurs in decompress_buf():
- OutputBuffer_Finish() => _BlocksOutputBuffer_Finish() => PyBytesWriter_FinishWithSize() => _PyBytes_Resize(): _PyBytes_Resize() fails with a memory allocation failure, then PyBytesWriter_FinishWithSize() calls PyBytesWriter_Discard()
- OutputBuffer_OnError() => _BlocksOutputBuffer_OnError(): call PyBytesWriter_Discard() again
Attached PR clears the writer in _BlocksOutputBuffer_Finish(), so _BlocksOutputBuffer_OnError() does nothing insted of calling PyBytesWriter_Discard() again.
Linked PRs
While testing injection of memory allocation failures in the
_bz2extension module, I found a bug:PyBytesWriter_Discard()is called twice on a memory allocation failure.Example:
The error occurs in decompress_buf():
Attached PR clears the writer in _BlocksOutputBuffer_Finish(), so _BlocksOutputBuffer_OnError() does nothing insted of calling PyBytesWriter_Discard() again.
Linked PRs