From f96b6475d48e9d62584842fc03bafa051963ddb5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 14 Sep 2026 23:12:45 +0200 Subject: [PATCH 1/6] gh-156939: Detect buffer overflow in bytes and bytearray When Python is built in debug mode, bytes an bytearray destructors now check if the trailing null byte has been overridden to detect overflow. Add bytes_dealloc() to implement the check. --- Lib/test/test_capi/test_bytearray.py | 21 ++++++++ Lib/test/test_capi/test_bytes.py | 18 +++++++ ...-09-14-23-16-26.gh-issue-156939.oZqlSt.rst | 3 ++ Modules/_testcapi/bytes.c | 33 +++++++++++++ Modules/_testcapi/mem.c | 2 + Objects/bytearrayobject.c | 15 ++++++ Objects/bytesobject.c | 49 +++++++++++++++---- 7 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-09-14-23-16-26.gh-issue-156939.oZqlSt.rst diff --git a/Lib/test/test_capi/test_bytearray.py b/Lib/test/test_capi/test_bytearray.py index cb7ad8b22252d9..04121dcfe1e287 100644 --- a/Lib/test/test_capi/test_bytearray.py +++ b/Lib/test/test_capi/test_bytearray.py @@ -1,6 +1,9 @@ import sys +import textwrap import unittest +from test import support from test.support import import_helper +from test.support.script_helper import assert_python_failure _testlimitedcapi = import_helper.import_module('_testlimitedcapi') from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX @@ -172,6 +175,24 @@ def test_resize(self): # CRASHES resize(object(), 0) # CRASHES resize(NULL, 0) + @unittest.skipUnless(support.Py_DEBUG, 'need debug build (Py_DEBUG)') + def test_detect_overflow(self): + # Test detection of buffer overflow + size = 123 + code = textwrap.dedent(f''' + from test.support import SuppressCrashReport + import _testcapi + + size = {size} + with SuppressCrashReport(): + # Trigger a buffer overflow in a new bytearray + ba = _testcapi.bytearray_overflow(size) + ba = None + ''') + proc = assert_python_failure('-c', code) + self.assertIn(b'Buffer overflow detected in bytearray object', proc.err) + self.assertIn(f'at position {size}'.encode(), proc.err) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi/test_bytes.py b/Lib/test/test_capi/test_bytes.py index a0006ea35e21fe..e3fcfb878e7dbc 100644 --- a/Lib/test/test_capi/test_bytes.py +++ b/Lib/test/test_capi/test_bytes.py @@ -317,6 +317,24 @@ def test_join(self): with self.assertRaises(SystemError): bytes_join(b'', NULL) + @unittest.skipUnless(support.Py_DEBUG, 'need debug build (Py_DEBUG)') + def test_detect_overflow(self): + # Test detection of buffer overflow + size = 123 + code = textwrap.dedent(f''' + from test.support import SuppressCrashReport + import _testcapi + + size = {size} + with SuppressCrashReport(): + # Trigger a buffer overflow in a new bytes + ba = _testcapi.bytes_overflow(size) + ba = None + ''') + proc = assert_python_failure('-c', code) + self.assertIn(b'Buffer overflow detected in bytes object', proc.err) + self.assertIn(f'at position {size}'.encode(), proc.err) + def get_data_canary(writer): size = writer.get_size() + 1 diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-09-14-23-16-26.gh-issue-156939.oZqlSt.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-09-14-23-16-26.gh-issue-156939.oZqlSt.rst new file mode 100644 index 00000000000000..212679fc0a79bf --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-09-14-23-16-26.gh-issue-156939.oZqlSt.rst @@ -0,0 +1,3 @@ +When Python is built in debug mode, :class:`bytes` and :class:`bytearray` +destructors now check if the trailing null byte has been overridden to detect +buffer overflow. Patch by Victor Stinner. diff --git a/Modules/_testcapi/bytes.c b/Modules/_testcapi/bytes.c index 79effcad40090e..5f284906ffcd7a 100644 --- a/Modules/_testcapi/bytes.c +++ b/Modules/_testcapi/bytes.c @@ -528,6 +528,37 @@ test_byteswriter_ptr(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) } +static PyObject * +bytes_overflow(PyObject *Py_UNUSED(module), PyObject *arg) +{ + PyObject *bytes = PyObject_CallOneArg((PyObject*)&PyBytes_Type, arg); + if (bytes == NULL) { + return NULL; + } + + char *data = PyBytes_AS_STRING(bytes); + Py_ssize_t size = PyBytes_GET_SIZE(bytes); + memset(data, 'x', size); + data[size] = '#'; // Buffer overflow! + return bytes; +} + + +static PyObject * +bytearray_overflow(PyObject *Py_UNUSED(module), PyObject *arg) +{ + PyObject *bytearray = PyObject_CallOneArg((PyObject*)&PyByteArray_Type, arg); + if (bytearray == NULL) { + return NULL; + } + + char *data = PyByteArray_AS_STRING(bytearray); + Py_ssize_t size = PyByteArray_GET_SIZE(bytearray); + data[size] = '#'; // Buffer overflow! + return bytearray; +} + + static PyMethodDef test_methods[] = { {"bytes_resize", bytes_resize, METH_VARARGS}, {"bytes_join", bytes_join, METH_VARARGS}, @@ -535,6 +566,8 @@ static PyMethodDef test_methods[] = { {"byteswriter_resize", byteswriter_resize, METH_NOARGS}, {"byteswriter_highlevel", byteswriter_highlevel, METH_NOARGS}, {"test_byteswriter_ptr", test_byteswriter_ptr, METH_NOARGS}, + {"bytes_overflow", bytes_overflow, METH_O}, + {"bytearray_overflow", bytearray_overflow, METH_O}, {NULL}, }; diff --git a/Modules/_testcapi/mem.c b/Modules/_testcapi/mem.c index 4ae6a60ff39d15..ba1462481231b5 100644 --- a/Modules/_testcapi/mem.c +++ b/Modules/_testcapi/mem.c @@ -448,6 +448,7 @@ test_pyobject_new(PyObject *self, PyObject *Py_UNUSED(ignored)) if (obj == NULL) { goto alloc_failed; } + memset(PyBytes_AS_STRING(obj), 0, 3 + 1); // +1 for the null byte Py_DECREF(obj); // PyObject_NEW_VAR() @@ -455,6 +456,7 @@ test_pyobject_new(PyObject *self, PyObject *Py_UNUSED(ignored)) if (obj == NULL) { goto alloc_failed; } + memset(PyBytes_AS_STRING(obj), 0, 3 + 1); // +1 for the null byte Py_DECREF(obj); Py_RETURN_NONE; diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index de30c6118ba176..fc967be081cb9a 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1272,6 +1272,21 @@ static void bytearray_dealloc(PyObject *op) { PyByteArrayObject *self = _PyByteArray_CAST(op); + +#ifdef Py_DEBUG + // Make sure that the trailing null byte was not modified + if (self->ob_bytes_object != NULL) { + char *data = PyByteArray_AS_STRING(self); + Py_ssize_t size = PyByteArray_GET_SIZE(self); + if (data[size] != '\0') { + _Py_FatalErrorFormat(__func__, + "Buffer overflow detected in bytearray " + "object %p at position %zd", + self, size); + } + } +#endif + if (self->ob_exports > 0) { PyErr_SetString(PyExc_SystemError, "deallocated bytearray object has exported buffers"); diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 117d8b56017b64..ad53ecb0296ed0 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3191,12 +3191,36 @@ bytes_iteritem(PyObject *obj, Py_ssize_t index) return (_PyObjectIndexPair) { .object = l, .index = index + 1 }; } +#ifdef Py_DEBUG +static void +bytes_dealloc(PyObject *op) +{ + // Make sure that the trailing null byte was not modified + PyBytesObject *self = _PyBytes_CAST(op); + char *data = PyBytes_AS_STRING(self); + Py_ssize_t size = PyBytes_GET_SIZE(self); + if (data[size] != '\0') { + _Py_FatalErrorFormat(__func__, + "Buffer overflow detected in bytes object %p " + "at position %zd", + self, size); + } + + Py_TYPE(self)->tp_free((PyObject *)self); +} +#endif + + PyTypeObject PyBytes_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "bytes", PyBytesObject_SIZE, sizeof(char), +#ifdef Py_DEBUG + bytes_dealloc, /* tp_dealloc */ +#else 0, /* tp_dealloc */ +#endif 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -3665,6 +3689,20 @@ byteswriter_write_canary_byte(PyBytesWriter *writer) unsigned char *data = (unsigned char*)byteswriter_data(writer); data[writer->size] = PyBytesWriter_CANARY_BYTE; } + + +static void +byteswriter_reset_trailing_byte(PyBytesWriter *writer) +{ + if (writer->obj != NULL) { + // PyBytesArray writes non-zero canary byte as the last byte. + // bytes/bytearray expects the last byte to be a null byte. + // Reset the last byte to null for bytes/bytearray. + Py_ssize_t allocated = byteswriter_allocated(writer); + char *data = byteswriter_data(writer); + data[allocated] = '\0'; + } +} #endif @@ -3814,6 +3852,7 @@ PyBytesWriter_Discard(PyBytesWriter *writer) #ifdef Py_DEBUG byteswriter_check_canary_byte(writer); + byteswriter_reset_trailing_byte(writer); #endif Py_XDECREF(writer->obj); @@ -3838,16 +3877,8 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size) } #ifdef Py_DEBUG - // Check for buffer overflow byteswriter_check_canary_byte(writer); - - if (writer->obj != NULL) { - // byteswriter_write_canary_byte() can override the trailing NUL byte. - // So reset the trailing NUL byte to NUL. - Py_ssize_t allocated = byteswriter_allocated(writer); - char *data = byteswriter_data(writer); - data[allocated] = '\0'; - } + byteswriter_reset_trailing_byte(writer); #endif PyObject *result; From e4c25dd403fc2db27313a882606af64573ef4af0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Sep 2026 04:17:44 +0200 Subject: [PATCH 2/6] Add _PyBytes_CheckOverflow() to share code --- Include/internal/pycore_bytesobject.h | 7 +++++++ Objects/bytearrayobject.c | 11 +---------- Objects/bytesobject.c | 16 +++++++++++----- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h index 443bdb26ff8738..8f764f0fa6d6e1 100644 --- a/Include/internal/pycore_bytesobject.h +++ b/Include/internal/pycore_bytesobject.h @@ -81,6 +81,13 @@ extern int _PyBytes_ResizeKeepOnError(PyObject **pv, Py_ssize_t newsize); extern int _PyBytes_IsMutable(PyObject *obj); #endif +#ifdef Py_DEBUG +extern void _PyBytes_CheckOverflow( + PyObject *op, + void *addr, + const char *type_name); +#endif + /* --- PyBytesWriter ------------------------------------------------------ */ struct PyBytesWriter { diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index fc967be081cb9a..16c38403547818 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1272,18 +1272,9 @@ static void bytearray_dealloc(PyObject *op) { PyByteArrayObject *self = _PyByteArray_CAST(op); - #ifdef Py_DEBUG - // Make sure that the trailing null byte was not modified if (self->ob_bytes_object != NULL) { - char *data = PyByteArray_AS_STRING(self); - Py_ssize_t size = PyByteArray_GET_SIZE(self); - if (data[size] != '\0') { - _Py_FatalErrorFormat(__func__, - "Buffer overflow detected in bytearray " - "object %p at position %zd", - self, size); - } + _PyBytes_CheckOverflow(self->ob_bytes_object, op, "bytearray"); } #endif diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index ad53ecb0296ed0..7a8833186351ec 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3192,20 +3192,26 @@ bytes_iteritem(PyObject *obj, Py_ssize_t index) } #ifdef Py_DEBUG -static void -bytes_dealloc(PyObject *op) +void +_PyBytes_CheckOverflow(PyObject *self, void *addr, const char *type_name) { // Make sure that the trailing null byte was not modified - PyBytesObject *self = _PyBytes_CAST(op); char *data = PyBytes_AS_STRING(self); Py_ssize_t size = PyBytes_GET_SIZE(self); if (data[size] != '\0') { _Py_FatalErrorFormat(__func__, - "Buffer overflow detected in bytes object %p " + "Buffer overflow detected in %s object %p " "at position %zd", - self, size); + type_name, addr, size); } +} + +static void +bytes_dealloc(PyObject *op) +{ + PyBytesObject *self = _PyBytes_CAST(op); + _PyBytes_CheckOverflow(op, op, "bytes"); Py_TYPE(self)->tp_free((PyObject *)self); } #endif From 26e185612617b3075863b54e642f9ff89e4de681 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Sep 2026 15:14:24 +0200 Subject: [PATCH 3/6] Fix typo PyBytesArray => PyBytesWriter Exit also earlier in byteswriter_reset_trailing_byte() --- Objects/bytesobject.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 7a8833186351ec..4451f557c20eec 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3700,14 +3700,16 @@ byteswriter_write_canary_byte(PyBytesWriter *writer) static void byteswriter_reset_trailing_byte(PyBytesWriter *writer) { - if (writer->obj != NULL) { - // PyBytesArray writes non-zero canary byte as the last byte. - // bytes/bytearray expects the last byte to be a null byte. - // Reset the last byte to null for bytes/bytearray. - Py_ssize_t allocated = byteswriter_allocated(writer); - char *data = byteswriter_data(writer); - data[allocated] = '\0'; + if (writer->obj == NULL) { + return; } + + // PyBytesWriter writes non-zero canary byte as the last byte. + // bytes/bytearray expects the last byte to be a null byte. + // Reset the last byte to null for bytes/bytearray. + Py_ssize_t allocated = byteswriter_allocated(writer); + char *data = byteswriter_data(writer); + data[allocated] = '\0'; } #endif From a69f37d821876f1437821a86f313a3cc4f0373e5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Sep 2026 15:20:14 +0200 Subject: [PATCH 4/6] Only reset the null byte when needed --- Objects/bytesobject.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 4451f557c20eec..06a2b382316b4e 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3700,10 +3700,6 @@ byteswriter_write_canary_byte(PyBytesWriter *writer) static void byteswriter_reset_trailing_byte(PyBytesWriter *writer) { - if (writer->obj == NULL) { - return; - } - // PyBytesWriter writes non-zero canary byte as the last byte. // bytes/bytearray expects the last byte to be a null byte. // Reset the last byte to null for bytes/bytearray. @@ -3860,7 +3856,9 @@ PyBytesWriter_Discard(PyBytesWriter *writer) #ifdef Py_DEBUG byteswriter_check_canary_byte(writer); - byteswriter_reset_trailing_byte(writer); + if (writer->obj != NULL) { + byteswriter_reset_trailing_byte(writer); + } #endif Py_XDECREF(writer->obj); @@ -3886,7 +3884,6 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size) #ifdef Py_DEBUG byteswriter_check_canary_byte(writer); - byteswriter_reset_trailing_byte(writer); #endif PyObject *result; @@ -3894,6 +3891,10 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size) result = bytes_get_empty(); } else if (writer->obj != NULL) { +#ifdef Py_DEBUG + byteswriter_reset_trailing_byte(writer); +#endif + if (writer->use_bytearray) { if (size != PyByteArray_GET_SIZE(writer->obj)) { if (PyByteArray_Resize(writer->obj, size)) { @@ -3920,12 +3921,15 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size) Py_SETREF(result, op); } } - else if (writer->use_bytearray) { - result = PyByteArray_FromStringAndSize(writer->small_buffer, size); - } else { - // The function returns single byte singleton if size equals 1 - result = PyBytes_FromStringAndSize(writer->small_buffer, size); + // Create an object from the small buffer + if (writer->use_bytearray) { + result = PyByteArray_FromStringAndSize(writer->small_buffer, size); + } + else { + // The function returns single byte singleton if size equals 1 + result = PyBytes_FromStringAndSize(writer->small_buffer, size); + } } #ifdef Py_DEBUG From fa56660a6026c7f094fa120aff8e334fd9bf6e09 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Sep 2026 15:22:12 +0200 Subject: [PATCH 5/6] Cleanup FinishWithSize code --- Objects/bytesobject.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 06a2b382316b4e..4f33b14a197eab 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3891,6 +3891,7 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size) result = bytes_get_empty(); } else if (writer->obj != NULL) { + // Truncate the bytes/bytearray object if needed #ifdef Py_DEBUG byteswriter_reset_trailing_byte(writer); #endif @@ -3908,18 +3909,18 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size) goto error; } } + + if (size == 1) { + // Get the single byte singleton + unsigned char ch = PyBytes_AS_STRING(writer->obj)[0]; + PyObject *op = (PyObject*)CHARACTER(ch); + assert(_Py_IsImmortal(op)); + Py_SETREF(writer->obj, op); + } } result = writer->obj; writer->obj = NULL; - - if (size == 1 && !writer->use_bytearray) { - // Get the single byte singleton - unsigned char ch = PyBytes_AS_STRING(result)[0]; - PyObject *op = (PyObject*)CHARACTER(ch); - assert(_Py_IsImmortal(op)); - Py_SETREF(result, op); - } } else { // Create an object from the small buffer From aeafe7d8e1176913932a7fa1e25df15778b6a0f1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Sep 2026 15:30:13 +0200 Subject: [PATCH 6/6] Allow buffer overflow of more than one byte --- Lib/test/test_capi/test_bytearray.py | 6 ++++-- Lib/test/test_capi/test_bytes.py | 6 ++++-- Modules/_testcapi/bytes.c | 24 ++++++++++++++++-------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_capi/test_bytearray.py b/Lib/test/test_capi/test_bytearray.py index 04121dcfe1e287..638a29f026cd97 100644 --- a/Lib/test/test_capi/test_bytearray.py +++ b/Lib/test/test_capi/test_bytearray.py @@ -178,15 +178,17 @@ def test_resize(self): @unittest.skipUnless(support.Py_DEBUG, 'need debug build (Py_DEBUG)') def test_detect_overflow(self): # Test detection of buffer overflow - size = 123 + size = 123 # bytes + overflow = 1 # bytes code = textwrap.dedent(f''' from test.support import SuppressCrashReport import _testcapi size = {size} + overflow = {overflow} with SuppressCrashReport(): # Trigger a buffer overflow in a new bytearray - ba = _testcapi.bytearray_overflow(size) + ba = _testcapi.bytearray_overflow(size, overflow) ba = None ''') proc = assert_python_failure('-c', code) diff --git a/Lib/test/test_capi/test_bytes.py b/Lib/test/test_capi/test_bytes.py index e3fcfb878e7dbc..12a1e88eac82d9 100644 --- a/Lib/test/test_capi/test_bytes.py +++ b/Lib/test/test_capi/test_bytes.py @@ -320,15 +320,17 @@ def test_join(self): @unittest.skipUnless(support.Py_DEBUG, 'need debug build (Py_DEBUG)') def test_detect_overflow(self): # Test detection of buffer overflow - size = 123 + size = 123 # bytes + overflow = 1 # bytes code = textwrap.dedent(f''' from test.support import SuppressCrashReport import _testcapi size = {size} + overflow = {overflow} with SuppressCrashReport(): # Trigger a buffer overflow in a new bytes - ba = _testcapi.bytes_overflow(size) + ba = _testcapi.bytes_overflow(size, overflow) ba = None ''') proc = assert_python_failure('-c', code) diff --git a/Modules/_testcapi/bytes.c b/Modules/_testcapi/bytes.c index 5f284906ffcd7a..e3d966b3bb1896 100644 --- a/Modules/_testcapi/bytes.c +++ b/Modules/_testcapi/bytes.c @@ -529,9 +529,13 @@ test_byteswriter_ptr(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) static PyObject * -bytes_overflow(PyObject *Py_UNUSED(module), PyObject *arg) +bytes_overflow(PyObject *Py_UNUSED(module), PyObject *args) { - PyObject *bytes = PyObject_CallOneArg((PyObject*)&PyBytes_Type, arg); + Py_ssize_t alloc, overflow = 1; + if (!PyArg_ParseTuple(args, "n|n", &alloc, &overflow)) + return NULL; + + PyObject *bytes = PyObject_CallFunction((PyObject*)&PyBytes_Type, "n", alloc); if (bytes == NULL) { return NULL; } @@ -539,22 +543,26 @@ bytes_overflow(PyObject *Py_UNUSED(module), PyObject *arg) char *data = PyBytes_AS_STRING(bytes); Py_ssize_t size = PyBytes_GET_SIZE(bytes); memset(data, 'x', size); - data[size] = '#'; // Buffer overflow! + memset(data + size, '#', overflow); // Buffer overflow! return bytes; } static PyObject * -bytearray_overflow(PyObject *Py_UNUSED(module), PyObject *arg) +bytearray_overflow(PyObject *Py_UNUSED(module), PyObject *args) { - PyObject *bytearray = PyObject_CallOneArg((PyObject*)&PyByteArray_Type, arg); + Py_ssize_t alloc, overflow = 1; + if (!PyArg_ParseTuple(args, "n|n", &alloc, &overflow)) + return NULL; + + PyObject *bytearray = PyObject_CallFunction((PyObject*)&PyByteArray_Type, "n", alloc); if (bytearray == NULL) { return NULL; } char *data = PyByteArray_AS_STRING(bytearray); Py_ssize_t size = PyByteArray_GET_SIZE(bytearray); - data[size] = '#'; // Buffer overflow! + memset(data + size, '#', overflow); // Buffer overflow! return bytearray; } @@ -566,8 +574,8 @@ static PyMethodDef test_methods[] = { {"byteswriter_resize", byteswriter_resize, METH_NOARGS}, {"byteswriter_highlevel", byteswriter_highlevel, METH_NOARGS}, {"test_byteswriter_ptr", test_byteswriter_ptr, METH_NOARGS}, - {"bytes_overflow", bytes_overflow, METH_O}, - {"bytearray_overflow", bytearray_overflow, METH_O}, + {"bytes_overflow", bytes_overflow, METH_VARARGS}, + {"bytearray_overflow", bytearray_overflow, METH_VARARGS}, {NULL}, };