[Python-checkins] cpython: Issue #1621: Fix undefined behaviour from signed overflow in datetime module

mark.dickinson python-checkins at python.org
Sun Sep 25 16:35:02 CEST 2011


http://hg.python.org/cpython/rev/3fb9464f9b02
changeset: 72468:3fb9464f9b02
user: Mark Dickinson <mdickinson at enthought.com>
date: Sun Sep 25 15:34:32 2011 +0100
summary:
 Issue #1621: Fix undefined behaviour from signed overflow in datetime module hashes, array and list iterations, and get_integer (stringlib/string_format.h)
files:
 Modules/_datetimemodule.c | 8 ++++----
 Modules/arraymodule.c | 2 +-
 Objects/listobject.c | 6 +++---
 Objects/stringlib/string_format.h | 14 ++++++--------
 4 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -2746,13 +2746,13 @@
 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;
 
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -2351,7 +2351,7 @@
 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,
diff --git a/Objects/listobject.c b/Objects/listobject.c
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -2434,7 +2434,7 @@
 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 @@
 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 @@
 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);
diff --git a/Objects/stringlib/string_format.h b/Objects/stringlib/string_format.h
--- a/Objects/stringlib/string_format.h
+++ b/Objects/stringlib/string_format.h
@@ -209,19 +209,17 @@
 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;
 }
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /