From 3f8707c23f419fabd1ff3e8e9243afc358a546e8 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Fri, 4 Dec 2009 11:25:29 +0000 Subject: [PATCH] Merged revisions 76665 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r76665 | mark.dickinson | 2009-12-04 11:24:38 +0000 (Fri, 04 Dec 2009) | 2 lines Avoid undefined behaviour due to overflow in i_divmod (Objects/intobject.c). ........ --- Objects/intobject.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Objects/intobject.c b/Objects/intobject.c index ebe029eac4a..406a45afefa 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -584,7 +584,16 @@ i_divmod(register long x, register long y, if (y == -1 && UNARY_NEG_WOULD_OVERFLOW(x)) return DIVMOD_OVERFLOW; xdivy = x / y; - xmody = x - xdivy * y; + /* xdiv*y can overflow on platforms where x/y gives floor(x/y) + * for x and y with differing signs. (This is unusual + * behaviour, and C99 prohibits it, but it's allowed by C89; + * for an example of overflow, take x = LONG_MIN, y = 5 or x = + * LONG_MAX, y = -5.) However, x - xdivy*y is always + * representable as a long, since it lies strictly between + * -abs(y) and abs(y). We add casts to avoid intermediate + * overflow. + */ + xmody = (long)(x - (unsigned long)xdivy * y); /* If the signs of x and y differ, and the remainder is non-0, * C89 doesn't define whether xdivy is now the floor or the * ceiling of the infinitely precise quotient. We want the floor,