Skip to content

Commit 829757c

Browse files
committed
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
1 parent 40482e6 commit 829757c

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

src/bin/pgbench/pgbench.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,29 @@ evaluateExpr(CState *st, PgBenchExpr *expr, int64 *retval)
961961
fprintf(stderr, "division by zero\n");
962962
return false;
963963
}
964-
*retval = lval / rval;
964+
965+
/*
966+
* INT64_MIN / -1 is problematic, since the result
967+
* can't be represented on a two's-complement machine.
968+
* Some machines produce INT64_MIN, some produce zero,
969+
* some throw an exception. We can dodge the problem
970+
* by recognizing that division by -1 is the same as
971+
* negation.
972+
*/
973+
if (rval == -1)
974+
{
975+
*retval = -lval;
976+
977+
/* overflow check (needed for INT64_MIN) */
978+
if (lval == PG_INT64_MIN)
979+
{
980+
fprintf(stderr, "bigint out of range\n");
981+
return false;
982+
}
983+
}
984+
else
985+
*retval = lval / rval;
986+
965987
return true;
966988

967989
case '%':
@@ -970,7 +992,17 @@ evaluateExpr(CState *st, PgBenchExpr *expr, int64 *retval)
970992
fprintf(stderr, "division by zero\n");
971993
return false;
972994
}
973-
*retval = lval % rval;
995+
996+
/*
997+
* Some machines throw a floating-point exception for
998+
* INT64_MIN % -1. Dodge that problem by noting that
999+
* any value modulo -1 is 0.
1000+
*/
1001+
if (rval == -1)
1002+
*retval = 0;
1003+
else
1004+
*retval = lval % rval;
1005+
9741006
return true;
9751007
}
9761008

0 commit comments

Comments
 (0)