From 64f5edca2401f6c2f23564da9dd52e92d08b3a20 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 1 Feb 2016 08:23:41 -0500 Subject: [PATCH] pgbench: Install guards against obscure overflow conditions. Dividing INT_MIN by -1 or taking INT_MIN modulo -1 can sometimes cause floating-point exceptions or otherwise misbehave. Fabien Coelho and Michael Paquier --- src/bin/pgbench/pgbench.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index 44da3d19c1..9bd822299b 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -1047,7 +1047,29 @@ evaluateExpr(CState *st, PgBenchExpr *expr, int64 *retval) fprintf(stderr, "division by zero\n"); return false; } - *retval = lval / rval; + + /* + * INT64_MIN / -1 is problematic, since the result + * can't be represented on a two's-complement machine. + * Some machines produce INT64_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 (rval == -1) + { + *retval = -lval; + + /* overflow check (needed for INT64_MIN) */ + if (lval == PG_INT64_MIN) + { + fprintf(stderr, "bigint out of range\n"); + return false; + } + } + else + *retval = lval / rval; + return true; case '%': @@ -1056,7 +1078,17 @@ evaluateExpr(CState *st, PgBenchExpr *expr, int64 *retval) fprintf(stderr, "division by zero\n"); return false; } - *retval = lval % rval; + + /* + * Some machines throw a floating-point exception for + * INT64_MIN % -1. Dodge that problem by noting that + * any value modulo -1 is 0. + */ + if (rval == -1) + *retval = 0; + else + *retval = lval % rval; + return true; } -- 2.40.0