From 02fe64708f809d00bfaa31fa7a7105ec2d7d28a1 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 11 Sep 2002 19:00:52 +0000 Subject: [PATCH] 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. Backport candidate. --- Objects/intobject.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/Objects/intobject.c b/Objects/intobject.c index 1b852c23f15..7404e980836 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -358,14 +358,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);