diff options
author | Armin Rigo <arigo@tunes.org> | 2016-10-07 22:50:10 +0200 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2016-10-07 22:50:10 +0200 |
commit | 99706a91350a092fd24848ab6a26875e70f9cb0c (patch) | |
tree | 18b3213372ad70a3e66b7636a2132e7f9ca0323b | |
parent | be6e220f8c7fe15ae9eadaf9df2697d267b852c5 (diff) | |
download | cffi-99706a91350a092fd24848ab6a26875e70f9cb0c.tar.gz |
Semi-blindly fix the muls and adds that could overflow so that gcc
doesn't optimize based on the assumption that they can't overflow
-rw-r--r-- | c/_cffi_backend.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c index 6da7912..d8eb006 100644 --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -266,6 +266,9 @@ typedef struct { Py_ssize_t exchange_offset_arg[1]; } cif_description_t; +#define ADD_WRAPAROUND(x, y) ((Py_ssize_t)(((size_t)(x)) + ((size_t)(y)))) +#define MUL_WRAPAROUND(x, y) ((Py_ssize_t)(((size_t)(x)) * ((size_t)(y)))) + /* whenever running Python code, the errno is saved in this thread-local variable */ @@ -1161,7 +1164,8 @@ convert_vfield_from_object(char *data, CFieldObject *cf, PyObject *value, Py_ssize_t size, itemsize; assert(data == NULL); itemsize = cf->cf_type->ct_itemdescr->ct_size; - size = cf->cf_offset + itemsize * varsizelength; + size = ADD_WRAPAROUND(cf->cf_offset, + MUL_WRAPAROUND(itemsize, varsizelength)); if (size < 0 || ((size - cf->cf_offset) / itemsize) != varsizelength) { PyErr_SetString(PyExc_OverflowError, @@ -2527,7 +2531,7 @@ _prepare_pointer_call_argument(CTypeDescrObject *ctptr, PyObject *init, if (ctitem->ct_size <= 0) goto convert_default; - datasize = length * ctitem->ct_size; + datasize = MUL_WRAPAROUND(length, ctitem->ct_size); if ((datasize / ctitem->ct_size) != length) { PyErr_SetString(PyExc_OverflowError, "array size would overflow a Py_ssize_t"); @@ -3181,7 +3185,7 @@ static PyObject *direct_newp(CTypeDescrObject *ct, PyObject *init, return NULL; ctitem = ct->ct_itemdescr; dataoffset = offsetof(CDataObject_own_length, alignment); - datasize = explicitlength * ctitem->ct_size; + datasize = MUL_WRAPAROUND(explicitlength, ctitem->ct_size); if (explicitlength > 0 && (datasize / explicitlength) != ctitem->ct_size) { PyErr_SetString(PyExc_OverflowError, @@ -4014,7 +4018,7 @@ new_array_type(CTypeDescrObject *ctptr, Py_ssize_t length) } else { sprintf(extra_text, "[%llu]", (unsigned PY_LONG_LONG)length); - arraysize = length * ctitem->ct_size; + arraysize = MUL_WRAPAROUND(length, ctitem->ct_size); if (length > 0 && (arraysize / length) != ctitem->ct_size) { PyErr_SetString(PyExc_OverflowError, "array size would overflow a Py_ssize_t"); @@ -5516,7 +5520,7 @@ static CTypeDescrObject *direct_typeoffsetof(CTypeDescrObject *ct, return NULL; } res = ct->ct_itemdescr; - *offset = index * ct->ct_itemdescr->ct_size; + *offset = MUL_WRAPAROUND(index, ct->ct_itemdescr->ct_size); if ((*offset / ct->ct_itemdescr->ct_size) != index) { PyErr_SetString(PyExc_OverflowError, "array offset would overflow a Py_ssize_t"); |