Issue #1621: Fix undefined behaviour from signed overflow in datetime module hashes, array and list iterations, and get_integer (stringlib/string_format.h)
This commit is contained in:
parent
50203a69b3
commit
c7d93b7614
|
@ -2746,13 +2746,13 @@ static Py_hash_t
|
|||
generic_hash(unsigned char *data, int len)
|
||||
{
|
||||
register unsigned char *p;
|
||||
register Py_hash_t x;
|
||||
register Py_uhash_t x;
|
||||
|
||||
p = (unsigned char *) data;
|
||||
x = *p << 7;
|
||||
x = (Py_uhash_t)*p << 7;
|
||||
while (--len >= 0)
|
||||
x = (1000003*x) ^ *p++;
|
||||
x ^= len;
|
||||
x = (1000003U*x) ^ (Py_uhash_t)*p++;
|
||||
x ^= (Py_uhash_t)len;
|
||||
if (x == -1)
|
||||
x = -2;
|
||||
|
||||
|
|
|
@ -2351,7 +2351,7 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
|
|||
self->ob_item + (cur + 1) * itemsize,
|
||||
lim * itemsize);
|
||||
}
|
||||
cur = start + slicelength * step;
|
||||
cur = start + (size_t)slicelength * step;
|
||||
if (cur < (size_t)Py_SIZE(self)) {
|
||||
memmove(self->ob_item + (cur-slicelength) * itemsize,
|
||||
self->ob_item + cur * itemsize,
|
||||
|
|
|
@ -2434,7 +2434,7 @@ list_subscript(PyListObject* self, PyObject* item)
|
|||
src = self->ob_item;
|
||||
dest = ((PyListObject *)result)->ob_item;
|
||||
for (cur = start, i = 0; i < slicelength;
|
||||
cur += step, i++) {
|
||||
cur += (size_t)step, i++) {
|
||||
it = src[cur];
|
||||
Py_INCREF(it);
|
||||
dest[i] = it;
|
||||
|
@ -2525,7 +2525,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
|
|||
self->ob_item + cur + 1,
|
||||
lim * sizeof(PyObject *));
|
||||
}
|
||||
cur = start + slicelength*step;
|
||||
cur = start + (size_t)slicelength * step;
|
||||
if (cur < (size_t)Py_SIZE(self)) {
|
||||
memmove(self->ob_item + cur - slicelength,
|
||||
self->ob_item + cur,
|
||||
|
@ -2589,7 +2589,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
|
|||
selfitems = self->ob_item;
|
||||
seqitems = PySequence_Fast_ITEMS(seq);
|
||||
for (cur = start, i = 0; i < slicelength;
|
||||
cur += step, i++) {
|
||||
cur += (size_t)step, i++) {
|
||||
garbage[i] = selfitems[cur];
|
||||
ins = seqitems[i];
|
||||
Py_INCREF(ins);
|
||||
|
|
|
@ -209,19 +209,17 @@ get_integer(const SubString *str)
|
|||
if (digitval < 0)
|
||||
return -1;
|
||||
/*
|
||||
This trick was copied from old Unicode format code. It's cute,
|
||||
but would really suck on an old machine with a slow divide
|
||||
implementation. Fortunately, in the normal case we do not
|
||||
expect too many digits.
|
||||
Detect possible overflow before it happens:
|
||||
|
||||
accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if
|
||||
accumulator > (PY_SSIZE_T_MAX - digitval) / 10.
|
||||
*/
|
||||
oldaccumulator = accumulator;
|
||||
accumulator *= 10;
|
||||
if ((accumulator+10)/10 != oldaccumulator+1) {
|
||||
if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"Too many decimal digits in format string");
|
||||
return -1;
|
||||
}
|
||||
accumulator += digitval;
|
||||
accumulator = accumulator * 10 + digitval;
|
||||
}
|
||||
return accumulator;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue