Fix range check in ECPG numeric to int conversion
The previous coding guarded against -INT_MAX instead of INT_MIN, leading to -2147483648 being rejected as out of range. Per bug #17128 from Kevin Sweet Discussion: https://www.postgresql.org/message-id/flat/17128-55a8a879727a3e3a%40postgresql.org Reviewed-by: Tom Lane Backpatch to all supported branches
This commit is contained in:
parent
41d27ee7b8
commit
171bf1cea5
@ -8666,7 +8666,7 @@ int dectoint(decimal *np, int *ip);
|
||||
Note that the ECPG implementation differs from the <productname>Informix</productname>
|
||||
implementation. <productname>Informix</productname> limits an integer to the range from -32767 to
|
||||
32767, while the limits in the ECPG implementation depend on the
|
||||
architecture (<literal>-INT_MAX .. INT_MAX</literal>).
|
||||
architecture (<literal>INT_MIN .. INT_MAX</literal>).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -1505,12 +1505,17 @@ PGTYPESnumeric_to_int(numeric *nv, int *ip)
|
||||
if ((i = PGTYPESnumeric_to_long(nv, &l)) != 0)
|
||||
return i;
|
||||
|
||||
if (l < -INT_MAX || l > INT_MAX)
|
||||
/* silence compilers that might complain about useless tests */
|
||||
#if SIZEOF_LONG > SIZEOF_INT
|
||||
|
||||
if (l < INT_MIN || l > INT_MAX)
|
||||
{
|
||||
errno = PGTYPES_NUM_OVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
*ip = (int) l;
|
||||
return 0;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ main(void)
|
||||
|
||||
double d;
|
||||
long l1, l2;
|
||||
int i;
|
||||
int i, min, max;
|
||||
|
||||
ECPGdebug(1, stderr);
|
||||
/* exec sql whenever sqlerror do sqlprint ( ) ; */
|
||||
@ -174,17 +174,28 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
|
||||
PGTYPESnumeric_free(value2);
|
||||
PGTYPESnumeric_free(res);
|
||||
|
||||
/* check conversion of numeric to int */
|
||||
value1 = PGTYPESnumeric_from_asc("-2147483648", NULL);
|
||||
PGTYPESnumeric_to_int(value1, &min);
|
||||
printf("min int = %d\n", min);
|
||||
PGTYPESnumeric_free(value1);
|
||||
|
||||
value2 = PGTYPESnumeric_from_asc("2147483647", NULL);
|
||||
PGTYPESnumeric_to_int(value2, &max);
|
||||
printf("max int = %d\n", max);
|
||||
PGTYPESnumeric_free(value2);
|
||||
|
||||
{ ECPGtrans(__LINE__, NULL, "rollback");
|
||||
#line 90 "num_test.pgc"
|
||||
#line 101 "num_test.pgc"
|
||||
|
||||
if (sqlca.sqlcode < 0) sqlprint ( );}
|
||||
#line 90 "num_test.pgc"
|
||||
#line 101 "num_test.pgc"
|
||||
|
||||
{ ECPGdisconnect(__LINE__, "CURRENT");
|
||||
#line 91 "num_test.pgc"
|
||||
#line 102 "num_test.pgc"
|
||||
|
||||
if (sqlca.sqlcode < 0) sqlprint ( );}
|
||||
#line 91 "num_test.pgc"
|
||||
#line 102 "num_test.pgc"
|
||||
|
||||
|
||||
return 0;
|
||||
|
@ -26,7 +26,7 @@
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_get_data on line 61: RESULT: 2369.7000000 offset: -1; array: no
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ECPGtrans on line 90: action "rollback"; connection "ecpg1_regression"
|
||||
[NO_PID]: ECPGtrans on line 101: action "rollback"; connection "ecpg1_regression"
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
[NO_PID]: ecpg_finish: connection ecpg1_regression closed
|
||||
[NO_PID]: sqlca: code: 0, state: 00000
|
||||
|
@ -4,3 +4,5 @@ sub = 2369.7
|
||||
mul = 13306998429.873000000
|
||||
div = 1330699.84298730000 1.3307e+06
|
||||
to long(0) = 20000000 14
|
||||
min int = -2147483648
|
||||
max int = 2147483647
|
||||
|
@ -19,7 +19,7 @@ main(void)
|
||||
exec sql end declare section;
|
||||
double d;
|
||||
long l1, l2;
|
||||
int i;
|
||||
int i, min, max;
|
||||
|
||||
ECPGdebug(1, stderr);
|
||||
exec sql whenever sqlerror do sqlprint();
|
||||
@ -87,6 +87,17 @@ main(void)
|
||||
PGTYPESnumeric_free(value2);
|
||||
PGTYPESnumeric_free(res);
|
||||
|
||||
/* check conversion of numeric to int */
|
||||
value1 = PGTYPESnumeric_from_asc("-2147483648", NULL);
|
||||
PGTYPESnumeric_to_int(value1, &min);
|
||||
printf("min int = %d\n", min);
|
||||
PGTYPESnumeric_free(value1);
|
||||
|
||||
value2 = PGTYPESnumeric_from_asc("2147483647", NULL);
|
||||
PGTYPESnumeric_to_int(value2, &max);
|
||||
printf("max int = %d\n", max);
|
||||
PGTYPESnumeric_free(value2);
|
||||
|
||||
exec sql rollback;
|
||||
exec sql disconnect;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user