summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-09-11 19:00:52 (GMT)
committerGuido van Rossum <guido@python.org>2002-09-11 19:00:52 (GMT)
commit02fe64708f809d00bfaa31fa7a7105ec2d7d28a1 (patch)
tree00bf849bf57a1ced47c3e0320cf516b9168d9cb0
parentf981a3373c1804fb79288f66a275ec095fd9acbf (diff)
downloadcpython-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.c33
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);