diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2009-12-04 11:25:29 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2009-12-04 11:25:29 (GMT) |
commit | 3f8707c23f419fabd1ff3e8e9243afc358a546e8 (patch) | |
tree | 2a0134f49cb2d0164d574343815120adda828ba1 /Objects | |
parent | 1b479f24dcc543cc3d992ddb7ffa2c01a7559ebc (diff) | |
download | cpython-3f8707c23f419fabd1ff3e8e9243afc358a546e8.zip cpython-3f8707c23f419fabd1ff3e8e9243afc358a546e8.tar.gz cpython-3f8707c23f419fabd1ff3e8e9243afc358a546e8.tar.bz2 |
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).
........
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/intobject.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/Objects/intobject.c b/Objects/intobject.c index ebe029e..406a45a 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, |