Martin v. Löwis <mar...@v.loewis.de> added the comment: > I'm finding many overflow checks that look like: > > size = Py_SIZE(a) * n; > if (n && size / n != Py_SIZE(a)) { > PyErr_SetString(PyExc_OverflowError, > "repeated bytes are too long"); > return NULL; > } > > where size and n have type Py_ssize_t. That particular one comes > from bytesobject.c (in py3k), but this style of check occurs > frequently throughout the source. > > Do people think that all these should be fixed?
If this really invokes undefined behavior already (i.e. a compiler could set "size" to -1, and have the test fail - ie. not give an exception, and still be conforming) - then absolutely yes. > The fix itself s reasonably straightforward: instead of multiplying > and then checking for an overflow that's already happened (and hence > has already invoked undefined behaviour according to the standards), > get an upper bound for n *first* by dividing PY_SSIZE_T_MAX > by Py_SIZE(a) and use that to do the overflow check *before* > the multiplication. It shouldn't be less efficient: either way > involves an integer division, a comparison, and a multiplication. [and then perform the multiplication unsigned, to silence the warning - right?] I think there is a second solution: perform the multiplication unsigned in the first place. For unsigned multiplication, IIUC, overflow behavior is guaranteed in standard C (i.e. it's modulo 2**N, where N is the number of value bits for the unsigned value). So the code would change to nbytes = (size_t)Py_SIZE(a)*n; if (n && (nbytes > Py_SSIZE_T_MAX || nbytes/n != Py_SIZE(a))... size = (Py_ssize_t)nbytes; ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue1621> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com