gh-111178: Fix function signatures in bytearrayobject.c (#124940)

This commit is contained in:
Victor Stinner 2024-10-04 11:59:51 +02:00 committed by GitHub
parent 6c7d5c6415
commit aace0dca8b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -42,15 +42,16 @@ _getbytevalue(PyObject* arg, int *value)
} }
static int static int
bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) bytearray_getbuffer(PyObject *self, Py_buffer *view, int flags)
{ {
void *ptr; PyByteArrayObject *obj = _PyByteArray_CAST(self);
if (view == NULL) { if (view == NULL) {
PyErr_SetString(PyExc_BufferError, PyErr_SetString(PyExc_BufferError,
"bytearray_getbuffer: view==NULL argument is obsolete"); "bytearray_getbuffer: view==NULL argument is obsolete");
return -1; return -1;
} }
ptr = (void *) PyByteArray_AS_STRING(obj);
void *ptr = (void *) PyByteArray_AS_STRING(obj);
/* cannot fail if view != NULL and readonly == 0 */ /* cannot fail if view != NULL and readonly == 0 */
(void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
obj->ob_exports++; obj->ob_exports++;
@ -58,8 +59,9 @@ bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
} }
static void static void
bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) bytearray_releasebuffer(PyObject *self, Py_buffer *view)
{ {
PyByteArrayObject *obj = _PyByteArray_CAST(self);
obj->ob_exports--; obj->ob_exports--;
assert(obj->ob_exports >= 0); assert(obj->ob_exports >= 0);
} }
@ -286,46 +288,53 @@ PyByteArray_Concat(PyObject *a, PyObject *b)
/* Functions stuffed into the type object */ /* Functions stuffed into the type object */
static Py_ssize_t static Py_ssize_t
bytearray_length(PyByteArrayObject *self) bytearray_length(PyObject *op)
{ {
PyByteArrayObject *self = _PyByteArray_CAST(op);
return Py_SIZE(self); return Py_SIZE(self);
} }
static PyObject * static PyObject *
bytearray_iconcat(PyByteArrayObject *self, PyObject *other) bytearray_iconcat(PyObject *op, PyObject *other)
{ {
Py_ssize_t size; PyByteArrayObject *self = _PyByteArray_CAST(op);
Py_buffer vo;
Py_buffer vo;
if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) { if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name); Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
return NULL; return NULL;
} }
size = Py_SIZE(self); Py_ssize_t size = Py_SIZE(self);
if (size > PY_SSIZE_T_MAX - vo.len) { if (size > PY_SSIZE_T_MAX - vo.len) {
PyBuffer_Release(&vo); PyBuffer_Release(&vo);
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) { if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) {
PyBuffer_Release(&vo); PyBuffer_Release(&vo);
return NULL; return NULL;
} }
memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len); memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len);
PyBuffer_Release(&vo); PyBuffer_Release(&vo);
return Py_NewRef(self); return Py_NewRef(self);
} }
static PyObject * static PyObject *
bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) bytearray_repeat(PyObject *op, Py_ssize_t count)
{ {
if (count < 0) PyByteArrayObject *self = _PyByteArray_CAST(op);
if (count < 0) {
count = 0; count = 0;
}
const Py_ssize_t mysize = Py_SIZE(self); const Py_ssize_t mysize = Py_SIZE(self);
if (count > 0 && mysize > PY_SSIZE_T_MAX / count) if (count > 0 && mysize > PY_SSIZE_T_MAX / count) {
return PyErr_NoMemory(); return PyErr_NoMemory();
}
Py_ssize_t size = mysize * count; Py_ssize_t size = mysize * count;
PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
const char* buf = PyByteArray_AS_STRING(self); const char* buf = PyByteArray_AS_STRING(self);
if (result != NULL && size != 0) { if (result != NULL && size != 0) {
@ -335,20 +344,24 @@ bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
} }
static PyObject * static PyObject *
bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) bytearray_irepeat(PyObject *op, Py_ssize_t count)
{ {
if (count < 0) PyByteArrayObject *self = _PyByteArray_CAST(op);
if (count < 0) {
count = 0; count = 0;
}
else if (count == 1) { else if (count == 1) {
return Py_NewRef(self); return Py_NewRef(self);
} }
const Py_ssize_t mysize = Py_SIZE(self); const Py_ssize_t mysize = Py_SIZE(self);
if (count > 0 && mysize > PY_SSIZE_T_MAX / count) if (count > 0 && mysize > PY_SSIZE_T_MAX / count) {
return PyErr_NoMemory(); return PyErr_NoMemory();
}
const Py_ssize_t size = mysize * count; const Py_ssize_t size = mysize * count;
if (PyByteArray_Resize((PyObject *)self, size) < 0) if (PyByteArray_Resize((PyObject *)self, size) < 0) {
return NULL; return NULL;
}
char* buf = PyByteArray_AS_STRING(self); char* buf = PyByteArray_AS_STRING(self);
_PyBytes_Repeat(buf, size, buf, mysize); _PyBytes_Repeat(buf, size, buf, mysize);
@ -357,8 +370,9 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
} }
static PyObject * static PyObject *
bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i) bytearray_getitem(PyObject *op, Py_ssize_t i)
{ {
PyByteArrayObject *self = _PyByteArray_CAST(op);
if (i < 0 || i >= Py_SIZE(self)) { if (i < 0 || i >= Py_SIZE(self)) {
PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
return NULL; return NULL;
@ -367,8 +381,9 @@ bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
} }
static PyObject * static PyObject *
bytearray_subscript(PyByteArrayObject *self, PyObject *index) bytearray_subscript(PyObject *op, PyObject *index)
{ {
PyByteArrayObject *self = _PyByteArray_CAST(op);
if (_PyIndex_Check(index)) { if (_PyIndex_Check(index)) {
Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError); Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
@ -559,12 +574,13 @@ bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
} }
static int static int
bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value) bytearray_setitem(PyObject *op, Py_ssize_t i, PyObject *value)
{ {
int ival = -1; PyByteArrayObject *self = _PyByteArray_CAST(op);
// GH-91153: We need to do this *before* the size check, in case value has a // GH-91153: We need to do this *before* the size check, in case value has a
// nasty __index__ method that changes the size of the bytearray: // nasty __index__ method that changes the size of the bytearray:
int ival = -1;
if (value && !_getbytevalue(value, &ival)) { if (value && !_getbytevalue(value, &ival)) {
return -1; return -1;
} }
@ -588,11 +604,11 @@ bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
} }
static int static int
bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values) bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values)
{ {
Py_ssize_t start, stop, step, slicelen, needed; PyByteArrayObject *self = _PyByteArray_CAST(op);
char *buf, *bytes; Py_ssize_t start, stop, step, slicelen;
buf = PyByteArray_AS_STRING(self); char *buf = PyByteArray_AS_STRING(self);
if (_PyIndex_Check(index)) { if (_PyIndex_Check(index)) {
Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError); Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
@ -645,6 +661,8 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
return -1; return -1;
} }
char *bytes;
Py_ssize_t needed;
if (values == NULL) { if (values == NULL) {
bytes = NULL; bytes = NULL;
needed = 0; needed = 0;
@ -661,7 +679,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
values = PyByteArray_FromObject(values); values = PyByteArray_FromObject(values);
if (values == NULL) if (values == NULL)
return -1; return -1;
err = bytearray_ass_subscript(self, index, values); err = bytearray_ass_subscript((PyObject*)self, index, values);
Py_DECREF(values); Py_DECREF(values);
return err; return err;
} }
@ -670,10 +688,14 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
bytes = PyByteArray_AS_STRING(values); bytes = PyByteArray_AS_STRING(values);
needed = Py_SIZE(values); needed = Py_SIZE(values);
} }
/* Make sure b[5:2] = ... inserts before 5, not before 2. */ /* Make sure b[5:2] = ... inserts before 5, not before 2. */
if ((step < 0 && start < stop) || if ((step < 0 && start < stop) ||
(step > 0 && start > stop)) (step > 0 && start > stop))
{
stop = start; stop = start;
}
if (step == 1) { if (step == 1) {
return bytearray_setslice_linear(self, start, stop, bytes, needed); return bytearray_setslice_linear(self, start, stop, bytes, needed);
} }
@ -785,7 +807,7 @@ bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
if (encoded == NULL) if (encoded == NULL)
return -1; return -1;
assert(PyBytes_Check(encoded)); assert(PyBytes_Check(encoded));
new = bytearray_iconcat(self, encoded); new = bytearray_iconcat((PyObject*)self, encoded);
Py_DECREF(encoded); Py_DECREF(encoded);
if (new == NULL) if (new == NULL)
return -1; return -1;
@ -926,8 +948,9 @@ slowpath:
/* Mostly copied from string_repr, but without the /* Mostly copied from string_repr, but without the
"smart quote" functionality. */ "smart quote" functionality. */
static PyObject * static PyObject *
bytearray_repr(PyByteArrayObject *self) bytearray_repr(PyObject *op)
{ {
PyByteArrayObject *self = _PyByteArray_CAST(op);
const char *className = _PyType_Name(Py_TYPE(self)); const char *className = _PyType_Name(Py_TYPE(self));
const char *quote_prefix = "(b"; const char *quote_prefix = "(b";
const char *quote_postfix = ")"; const char *quote_postfix = ")";
@ -1021,7 +1044,7 @@ bytearray_str(PyObject *op)
return NULL; return NULL;
} }
} }
return bytearray_repr((PyByteArrayObject*)op); return bytearray_repr(op);
} }
static PyObject * static PyObject *
@ -1080,8 +1103,9 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op)
} }
static void static void
bytearray_dealloc(PyByteArrayObject *self) bytearray_dealloc(PyObject *op)
{ {
PyByteArrayObject *self = _PyByteArray_CAST(op);
if (self->ob_exports > 0) { if (self->ob_exports > 0) {
PyErr_SetString(PyExc_SystemError, PyErr_SetString(PyExc_SystemError,
"deallocated bytearray object has exported buffers"); "deallocated bytearray object has exported buffers");
@ -1244,7 +1268,9 @@ bytearray_rindex_impl(PyByteArrayObject *self, PyObject *sub,
static int static int
bytearray_contains(PyObject *self, PyObject *arg) bytearray_contains(PyObject *self, PyObject *arg)
{ {
return _Py_bytes_contains(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), arg); return _Py_bytes_contains(PyByteArray_AS_STRING(self),
PyByteArray_GET_SIZE(self),
arg);
} }
/*[clinic input] /*[clinic input]
@ -2262,31 +2288,30 @@ bytearray_sizeof_impl(PyByteArrayObject *self)
} }
static PySequenceMethods bytearray_as_sequence = { static PySequenceMethods bytearray_as_sequence = {
(lenfunc)bytearray_length, /* sq_length */ bytearray_length, /* sq_length */
(binaryfunc)PyByteArray_Concat, /* sq_concat */ PyByteArray_Concat, /* sq_concat */
(ssizeargfunc)bytearray_repeat, /* sq_repeat */ bytearray_repeat, /* sq_repeat */
(ssizeargfunc)bytearray_getitem, /* sq_item */ bytearray_getitem, /* sq_item */
0, /* sq_slice */ 0, /* sq_slice */
(ssizeobjargproc)bytearray_setitem, /* sq_ass_item */ bytearray_setitem, /* sq_ass_item */
0, /* sq_ass_slice */ 0, /* sq_ass_slice */
(objobjproc)bytearray_contains, /* sq_contains */ bytearray_contains, /* sq_contains */
(binaryfunc)bytearray_iconcat, /* sq_inplace_concat */ bytearray_iconcat, /* sq_inplace_concat */
(ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */ bytearray_irepeat, /* sq_inplace_repeat */
}; };
static PyMappingMethods bytearray_as_mapping = { static PyMappingMethods bytearray_as_mapping = {
(lenfunc)bytearray_length, bytearray_length,
(binaryfunc)bytearray_subscript, bytearray_subscript,
(objobjargproc)bytearray_ass_subscript, bytearray_ass_subscript,
}; };
static PyBufferProcs bytearray_as_buffer = { static PyBufferProcs bytearray_as_buffer = {
(getbufferproc)bytearray_getbuffer, bytearray_getbuffer,
(releasebufferproc)bytearray_releasebuffer, bytearray_releasebuffer,
}; };
static PyMethodDef static PyMethodDef bytearray_methods[] = {
bytearray_methods[] = {
{"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
BYTEARRAY_REDUCE_METHODDEF BYTEARRAY_REDUCE_METHODDEF
BYTEARRAY_REDUCE_EX_METHODDEF BYTEARRAY_REDUCE_EX_METHODDEF
@ -2391,12 +2416,12 @@ PyTypeObject PyByteArray_Type = {
"bytearray", "bytearray",
sizeof(PyByteArrayObject), sizeof(PyByteArrayObject),
0, 0,
(destructor)bytearray_dealloc, /* tp_dealloc */ bytearray_dealloc, /* tp_dealloc */
0, /* tp_vectorcall_offset */ 0, /* tp_vectorcall_offset */
0, /* tp_getattr */ 0, /* tp_getattr */
0, /* tp_setattr */ 0, /* tp_setattr */
0, /* tp_as_async */ 0, /* tp_as_async */
(reprfunc)bytearray_repr, /* tp_repr */ bytearray_repr, /* tp_repr */
&bytearray_as_number, /* tp_as_number */ &bytearray_as_number, /* tp_as_number */
&bytearray_as_sequence, /* tp_as_sequence */ &bytearray_as_sequence, /* tp_as_sequence */
&bytearray_as_mapping, /* tp_as_mapping */ &bytearray_as_mapping, /* tp_as_mapping */
@ -2411,7 +2436,7 @@ PyTypeObject PyByteArray_Type = {
bytearray_doc, /* tp_doc */ bytearray_doc, /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
(richcmpfunc)bytearray_richcompare, /* tp_richcompare */ bytearray_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */ 0, /* tp_weaklistoffset */
bytearray_iter, /* tp_iter */ bytearray_iter, /* tp_iter */
0, /* tp_iternext */ 0, /* tp_iternext */