mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
Fix integer-overflow edge case detection in interval_mul and pgbench.
This patch adopts the overflow check logic introduced by commitcbdb8b4c0
into two more places. interval_mul() failed to notice if it computed a new microseconds value that was one more than INT64_MAX, and pgbench's double-to-int64 logic had the same sorts of edge-case problems thatcbdb8b4c0
fixed in the core code. To make this easier to get right in future, put the guts of the checks into new macros in c.h, and add commentary about how to use the macros correctly. Back-patch to all supported branches, as we did with the previous fix. Yuya Watari Discussion: https://postgr.es/m/CAJ2pMkbkkFw2hb9Qb1Zj8d06EhWAQXFLy73St4qWv6aX=vqnjw@mail.gmail.com
This commit is contained in:
@ -1212,15 +1212,8 @@ dtoi4(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
num = rint(num);
|
||||
|
||||
/*
|
||||
* Range check. We must be careful here that the boundary values are
|
||||
* expressed exactly in the float domain. We expect PG_INT32_MIN to be an
|
||||
* exact power of 2, so it will be represented exactly; but PG_INT32_MAX
|
||||
* isn't, and might get rounded off, so avoid using it.
|
||||
*/
|
||||
if (unlikely(num < (float8) PG_INT32_MIN ||
|
||||
num >= -((float8) PG_INT32_MIN) ||
|
||||
isnan(num)))
|
||||
/* Range check */
|
||||
if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT32(num)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("integer out of range")));
|
||||
@ -1244,15 +1237,8 @@ dtoi2(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
num = rint(num);
|
||||
|
||||
/*
|
||||
* Range check. We must be careful here that the boundary values are
|
||||
* expressed exactly in the float domain. We expect PG_INT16_MIN to be an
|
||||
* exact power of 2, so it will be represented exactly; but PG_INT16_MAX
|
||||
* isn't, and might get rounded off, so avoid using it.
|
||||
*/
|
||||
if (unlikely(num < (float8) PG_INT16_MIN ||
|
||||
num >= -((float8) PG_INT16_MIN) ||
|
||||
isnan(num)))
|
||||
/* Range check */
|
||||
if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT16(num)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("smallint out of range")));
|
||||
@ -1300,15 +1286,8 @@ ftoi4(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
num = rint(num);
|
||||
|
||||
/*
|
||||
* Range check. We must be careful here that the boundary values are
|
||||
* expressed exactly in the float domain. We expect PG_INT32_MIN to be an
|
||||
* exact power of 2, so it will be represented exactly; but PG_INT32_MAX
|
||||
* isn't, and might get rounded off, so avoid using it.
|
||||
*/
|
||||
if (unlikely(num < (float4) PG_INT32_MIN ||
|
||||
num >= -((float4) PG_INT32_MIN) ||
|
||||
isnan(num)))
|
||||
/* Range check */
|
||||
if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT32(num)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("integer out of range")));
|
||||
@ -1332,15 +1311,8 @@ ftoi2(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
num = rint(num);
|
||||
|
||||
/*
|
||||
* Range check. We must be careful here that the boundary values are
|
||||
* expressed exactly in the float domain. We expect PG_INT16_MIN to be an
|
||||
* exact power of 2, so it will be represented exactly; but PG_INT16_MAX
|
||||
* isn't, and might get rounded off, so avoid using it.
|
||||
*/
|
||||
if (unlikely(num < (float4) PG_INT16_MIN ||
|
||||
num >= -((float4) PG_INT16_MIN) ||
|
||||
isnan(num)))
|
||||
/* Range check */
|
||||
if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT16(num)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("smallint out of range")));
|
||||
|
Reference in New Issue
Block a user