From b63a4f418f5611272f28d0633932ffbf3bbd3015 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Wed, 3 Feb 2016 09:15:29 -0500
Subject: [PATCH] pgbench: Install guard against overflow when dividing by -1.

Commit 64f5edca2401f6c2f23564da9dd52e92d08b3a20 fixed the same hazard
on master; this is a backport, but the modulo operator does not exist
in older releases.

Michael Paquier
---
 contrib/pgbench/pgbench.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c
index 2111f16f358..84b630336fe 100644
--- a/contrib/pgbench/pgbench.c
+++ b/contrib/pgbench/pgbench.c
@@ -56,6 +56,10 @@
 #ifndef INT64_MAX
 #define INT64_MAX	INT64CONST(0x7FFFFFFFFFFFFFFF)
 #endif
+#ifndef INT32_MIN
+#define INT32_MIN	(-0x7FFFFFFF-1)
+#endif
+
 
 /*
  * Multi-platform pthread implementations
@@ -1152,13 +1156,37 @@ top:
 					snprintf(res, sizeof(res), "%d", ope1 * ope2);
 				else if (strcmp(argv[3], "/") == 0)
 				{
+					int		operes;
+
 					if (ope2 == 0)
 					{
 						fprintf(stderr, "%s: division by zero\n", argv[0]);
 						st->ecnt++;
 						return true;
 					}
-					snprintf(res, sizeof(res), "%d", ope1 / ope2);
+					/*
+					 * INT32_MIN / -1 is problematic, since the result can't
+					 * be represented on a two's-complement machine. Some
+					 * machines produce INT32_MIN, some produce zero, some
+					 * throw an exception. We can dodge the problem by
+					 * recognizing that division by -1 is the same as
+					 * negation.
+					 */
+					if (ope2 == -1)
+					{
+						operes = -ope1;
+
+						/* overflow check (needed for INT32_MIN) */
+						if (ope1 == INT32_MIN)
+						{
+							fprintf(stderr, "integer out of range\n");
+							st->ecnt++;
+							return true;
+						}
+					}
+					else
+						operes = ope1 / ope2;
+					snprintf(res, sizeof(res), "%d", operes);
 				}
 				else
 				{
-- 
GitLab