Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r2780:df6e80806eb4
Date: 2016-10-07 22:50 +0200
http://bitbucket.org/cffi/cffi/changeset/df6e80806eb4/

Log:    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

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -266,6 +266,9 @@
     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 @@
             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 @@
 
     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 @@
                 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 @@
     }
     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 @@
             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");
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to