Mark Dickinson avatar Mark Dickinson committed 040c38e

Avoid undefined behaviour due to overflow in i_divmod (Objects/intobject.c).

Comments (0)

Files changed (1)

Objects/intobject.c

 	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,
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.