summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-07-10 17:51:35 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-07-10 17:51:35 (GMT)
commitca0da9b0a3be265b6e0744bba2391d6ae77f47ab (patch)
tree7f42eb3c8a3a0e8239977ae1495a8b7bc56127bc
parentce85acff3a28cd4c3ded487bfbc8c8ac5462d4e4 (diff)
parent06cfb0cd7037795cc7dca2729a241ed2a1fb1628 (diff)
downloadcpython-ca0da9b0a3be265b6e0744bba2391d6ae77f47ab.zip
cpython-ca0da9b0a3be265b6e0744bba2391d6ae77f47ab.tar.gz
cpython-ca0da9b0a3be265b6e0744bba2391d6ae77f47ab.tar.bz2
Issue #27473: Fixed possible integer overflow in bytes and bytearray
concatenations. Patch by Xiang Zhang.
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/bytearrayobject.c21
-rw-r--r--Objects/bytesobject.c6
3 files changed, 14 insertions, 16 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 6c646b6..de83c78 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.6.0 alpha 3
Core and Builtins
-----------------
+- Issue #27473: Fixed possible integer overflow in bytes and bytearray
+ concatenations. Patch by Xiang Zhang.
+
- Issue #23034: The output of a special Python build with defined COUNT_ALLOCS,
SHOW_ALLOC_COUNT or SHOW_TRACK_COUNT macros is now off by default. It can
be re-enabled using the "-X showalloccount" option. It now outputs to stderr
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 50da637..4990b3e 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -246,7 +246,6 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
PyObject *
PyByteArray_Concat(PyObject *a, PyObject *b)
{
- Py_ssize_t size;
Py_buffer va, vb;
PyByteArrayObject *result = NULL;
@@ -259,13 +258,13 @@ PyByteArray_Concat(PyObject *a, PyObject *b)
goto done;
}
- size = va.len + vb.len;
- if (size < 0) {
- PyErr_NoMemory();
- goto done;
+ if (va.len > PY_SSIZE_T_MAX - vb.len) {
+ PyErr_NoMemory();
+ goto done;
}
- result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
+ result = (PyByteArrayObject *) \
+ PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
if (result != NULL) {
memcpy(result->ob_bytes, va.buf, va.len);
memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
@@ -290,7 +289,6 @@ bytearray_length(PyByteArrayObject *self)
static PyObject *
bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
{
- Py_ssize_t mysize;
Py_ssize_t size;
Py_buffer vo;
@@ -300,17 +298,16 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
return NULL;
}
- mysize = Py_SIZE(self);
- size = mysize + vo.len;
- if (size < 0) {
+ size = Py_SIZE(self);
+ if (size > PY_SSIZE_T_MAX - vo.len) {
PyBuffer_Release(&vo);
return PyErr_NoMemory();
}
- if (PyByteArray_Resize((PyObject *)self, size) < 0) {
+ if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) {
PyBuffer_Release(&vo);
return NULL;
}
- memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
+ memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len);
PyBuffer_Release(&vo);
Py_INCREF(self);
return (PyObject *)self;
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 1ef21cc..5f77867 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -1388,7 +1388,6 @@ bytes_length(PyBytesObject *a)
static PyObject *
bytes_concat(PyObject *a, PyObject *b)
{
- Py_ssize_t size;
Py_buffer va, vb;
PyObject *result = NULL;
@@ -1413,13 +1412,12 @@ bytes_concat(PyObject *a, PyObject *b)
goto done;
}
- size = va.len + vb.len;
- if (size < 0) {
+ if (va.len > PY_SSIZE_T_MAX - vb.len) {
PyErr_NoMemory();
goto done;
}
- result = PyBytes_FromStringAndSize(NULL, size);
+ result = PyBytes_FromStringAndSize(NULL, va.len + vb.len);
if (result != NULL) {
memcpy(PyBytes_AS_STRING(result), va.buf, va.len);
memcpy(PyBytes_AS_STRING(result) + va.len, vb.buf, vb.len);