Skip to content

Commit 06cfb0c

Browse files
Issue python#27473: Fixed possible integer overflow in bytes and bytearray
concatenations. Patch by Xiang Zhang.
1 parent 537ad7a commit 06cfb0c

3 files changed

Lines changed: 14 additions & 16 deletions

File tree

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Release date: TBA
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #27473: Fixed possible integer overflow in bytes and bytearray
14+
concatenations. Patch by Xiang Zhang.
15+
1316
- Issue #27443: __length_hint__() of bytearray itearator no longer return
1417
negative integer for resized bytearray.
1518

‎Objects/bytearrayobject.c‎

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
246246
PyObject *
247247
PyByteArray_Concat(PyObject *a, PyObject *b)
248248
{
249-
Py_ssize_t size;
250249
Py_buffer va, vb;
251250
PyByteArrayObject *result = NULL;
252251

@@ -259,13 +258,13 @@ PyByteArray_Concat(PyObject *a, PyObject *b)
259258
goto done;
260259
}
261260

262-
size = va.len + vb.len;
263-
if (size < 0) {
264-
PyErr_NoMemory();
265-
goto done;
261+
if (va.len > PY_SSIZE_T_MAX - vb.len) {
262+
PyErr_NoMemory();
263+
goto done;
266264
}
267265

268-
result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
266+
result = (PyByteArrayObject *) \
267+
PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
269268
if (result != NULL) {
270269
memcpy(result->ob_bytes, va.buf, va.len);
271270
memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
@@ -315,7 +314,6 @@ bytearray_length(PyByteArrayObject *self)
315314
static PyObject *
316315
bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
317316
{
318-
Py_ssize_t mysize;
319317
Py_ssize_t size;
320318
Py_buffer vo;
321319

@@ -325,17 +323,16 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
325323
return NULL;
326324
}
327325

328-
mysize = Py_SIZE(self);
329-
size = mysize + vo.len;
330-
if (size < 0) {
326+
size = Py_SIZE(self);
327+
if (size > PY_SSIZE_T_MAX - vo.len) {
331328
PyBuffer_Release(&vo);
332329
return PyErr_NoMemory();
333330
}
334-
if (PyByteArray_Resize((PyObject *)self, size) < 0) {
331+
if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) {
335332
PyBuffer_Release(&vo);
336333
return NULL;
337334
}
338-
memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
335+
memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len);
339336
PyBuffer_Release(&vo);
340337
Py_INCREF(self);
341338
return (PyObject *)self;

‎Objects/bytesobject.c‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,6 @@ bytes_length(PyBytesObject *a)
12651265
static PyObject *
12661266
bytes_concat(PyObject *a, PyObject *b)
12671267
{
1268-
Py_ssize_t size;
12691268
Py_buffer va, vb;
12701269
PyObject *result = NULL;
12711270

@@ -1290,13 +1289,12 @@ bytes_concat(PyObject *a, PyObject *b)
12901289
goto done;
12911290
}
12921291

1293-
size = va.len + vb.len;
1294-
if (size < 0) {
1292+
if (va.len > PY_SSIZE_T_MAX - vb.len) {
12951293
PyErr_NoMemory();
12961294
goto done;
12971295
}
12981296

1299-
result = PyBytes_FromStringAndSize(NULL, size);
1297+
result = PyBytes_FromStringAndSize(NULL, va.len + vb.len);
13001298
if (result != NULL) {
13011299
memcpy(PyBytes_AS_STRING(result), va.buf, va.len);
13021300
memcpy(PyBytes_AS_STRING(result) + va.len, vb.buf, vb.len);

0 commit comments

Comments
 (0)