]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Backport 2.93 from trunk:
authorGuido van Rossum <guido@python.org>
Mon, 23 Sep 2002 21:02:33 +0000 (21:02 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 23 Sep 2002 21:02:33 +0000 (21:02 +0000)
Insert an overflow check when the sequence repetition count is outside
the range of ints.  The old code would pass random truncated bits to
sq_repeat() on a 64-bit machine.

Objects/intobject.c

index 5daf699ec88d8fc4db18b4856e1b745b28a64b23..ee617654863db7e3477c1e6da0f676ce4dc245c6 100644 (file)
@@ -361,14 +361,41 @@ int_mul(PyObject *v, PyObject *w)
        double doubleprod;              /* (double)a * (double)b */
 
        if (USE_SQ_REPEAT(v)) {
+         repeat:
                /* sequence * int */
                a = PyInt_AsLong(w);
+#if LONG_MAX != INT_MAX
+               if (a > INT_MAX) {
+                       PyErr_SetString(PyExc_ValueError,
+                                       "sequence repeat count too large");
+                       return NULL;
+               }
+               else if (a < INT_MIN)
+                       a = INT_MIN;
+               /* XXX Why don't I either
+
+                  - set a to -1 whenever it's negative (after all,
+                    sequence repeat usually treats negative numbers
+                    as zero(); or
+
+                  - raise an exception when it's less than INT_MIN?
+
+                  I'm thinking about a hypothetical use case where some
+                  sequence type might use a negative value as a flag of
+                  some kind.  In those cases I don't want to break the
+                  code by mapping all negative values to -1.  But I also
+                  don't want to break e.g. []*(-sys.maxint), which is
+                  perfectly safe, returning [].  As a compromise, I do
+                  map out-of-range negative values.
+               */
+#endif
                return (*v->ob_type->tp_as_sequence->sq_repeat)(v, a);
        }
        if (USE_SQ_REPEAT(w)) {
-               /* int * sequence */
-               a = PyInt_AsLong(v);
-               return (*w->ob_type->tp_as_sequence->sq_repeat)(w, a);
+               PyObject *tmp = v;
+               v = w;
+               w = tmp;
+               goto repeat;
        }
 
        CONVERT_TO_LONG(v, a);