summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2016-02-03 09:15:29 -0500
committerRobert Haas <rhaas@postgresql.org>2016-02-03 09:25:34 -0500
commit4c8b07d3c4300dd9e6e3a8b6dc8260c128a9cd75 (patch)
treeeb4538e4b95c99f39e77216aa9af221809986f3a
parent79782b4075ab03708e3cc645b77b9a2635d85afa (diff)
downloadpostgresql-4c8b07d3c4300dd9e6e3a8b6dc8260c128a9cd75.tar.gz
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
-rw-r--r--contrib/pgbench/pgbench.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c
index 97dcad0ce6..035024d6f5 100644
--- a/contrib/pgbench/pgbench.c
+++ b/contrib/pgbench/pgbench.c
@@ -59,6 +59,10 @@
#ifndef INT64_MAX
#define INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF)
#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-0x7FFFFFFF-1)
+#endif
+
/*
* Multi-platform pthread implementations
@@ -1112,13 +1116,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
{