Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 64f5edc

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 89611c4 commit 64f5edc

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
@@ -1047,7 +1047,29 @@ evaluateExpr(CState *st, PgBenchExpr *expr, int64 *retval)
10471047
fprintf(stderr, "division by zero\n");
10481048
return false;
10491049
}
1050-
*retval = lval / rval;
1050+
1051+
/*
1052+
* INT64_MIN / -1 is problematic, since the result
1053+
* can't be represented on a two's-complement machine.
1054+
* Some machines produce INT64_MIN, some produce zero,
1055+
* some throw an exception. We can dodge the problem
1056+
* by recognizing that division by -1 is the same as
1057+
* negation.
1058+
*/
1059+
if (rval == -1)
1060+
{
1061+
*retval = -lval;
1062+
1063+
/* overflow check (needed for INT64_MIN) */
1064+
if (lval == PG_INT64_MIN)
1065+
{
1066+
fprintf(stderr, "bigint out of range\n");
1067+
return false;
1068+
}
1069+
}
1070+
else
1071+
*retval = lval / rval;
1072+
10511073
return true;
10521074

10531075
case '%':
@@ -1056,7 +1078,17 @@ evaluateExpr(CState *st, PgBenchExpr *expr, int64 *retval)
10561078
fprintf(stderr, "division by zero\n");
10571079
return false;
10581080
}
1059-
*retval = lval % rval;
1081+
1082+
/*
1083+
* Some machines throw a floating-point exception for
1084+
* INT64_MIN % -1. Dodge that problem by noting that
1085+
* any value modulo -1 is 0.
1086+
*/
1087+
if (rval == -1)
1088+
*retval = 0;
1089+
else
1090+
*retval = lval % rval;
1091+
10601092
return true;
10611093
}
10621094

0 commit comments

Comments
 (0)