diff options
author | Guido van Rossum <guido@python.org> | 2002-09-11 19:00:52 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2002-09-11 19:00:52 (GMT) |
commit | 02fe64708f809d00bfaa31fa7a7105ec2d7d28a1 (patch) | |
tree | 00bf849bf57a1ced47c3e0320cf516b9168d9cb0 | |
parent | f981a3373c1804fb79288f66a275ec095fd9acbf (diff) | |
download | cpython-02fe64708f809d00bfaa31fa7a7105ec2d7d28a1.zip cpython-02fe64708f809d00bfaa31fa7a7105ec2d7d28a1.tar.gz cpython-02fe64708f809d00bfaa31fa7a7105ec2d7d28a1.tar.bz2 |
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.
-rw-r--r-- | Objects/intobject.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/Objects/intobject.c b/Objects/intobject.c index 1b852c2..7404e98 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); |