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>
|
Note that the ECPG implementation differs from the <productname>Informix</productname>
|
||||||
implementation. <productname>Informix</productname> limits an integer to the range from -32767 to
|
implementation. <productname>Informix</productname> limits an integer to the range from -32767 to
|
||||||
32767, while the limits in the ECPG implementation depend on the
|
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>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -1505,12 +1505,17 @@ PGTYPESnumeric_to_int(numeric *nv, int *ip)
|
|||||||
if ((i = PGTYPESnumeric_to_long(nv, &l)) != 0)
|
if ((i = PGTYPESnumeric_to_long(nv, &l)) != 0)
|
||||||
return i;
|
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;
|
errno = PGTYPES_NUM_OVERFLOW;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
*ip = (int) l;
|
*ip = (int) l;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ main(void)
|
|||||||
|
|
||||||
double d;
|
double d;
|
||||||
long l1, l2;
|
long l1, l2;
|
||||||
int i;
|
int i, min, max;
|
||||||
|
|
||||||
ECPGdebug(1, stderr);
|
ECPGdebug(1, stderr);
|
||||||
/* exec sql whenever sqlerror do sqlprint ( ) ; */
|
/* exec sql whenever sqlerror do sqlprint ( ) ; */
|
||||||
@ -174,17 +174,28 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
|
|||||||
PGTYPESnumeric_free(value2);
|
PGTYPESnumeric_free(value2);
|
||||||
PGTYPESnumeric_free(res);
|
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");
|
{ ECPGtrans(__LINE__, NULL, "rollback");
|
||||||
#line 90 "num_test.pgc"
|
#line 101 "num_test.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint ( );}
|
if (sqlca.sqlcode < 0) sqlprint ( );}
|
||||||
#line 90 "num_test.pgc"
|
#line 101 "num_test.pgc"
|
||||||
|
|
||||||
{ ECPGdisconnect(__LINE__, "CURRENT");
|
{ ECPGdisconnect(__LINE__, "CURRENT");
|
||||||
#line 91 "num_test.pgc"
|
#line 102 "num_test.pgc"
|
||||||
|
|
||||||
if (sqlca.sqlcode < 0) sqlprint ( );}
|
if (sqlca.sqlcode < 0) sqlprint ( );}
|
||||||
#line 91 "num_test.pgc"
|
#line 102 "num_test.pgc"
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
[NO_PID]: sqlca: code: 0, state: 00000
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
[NO_PID]: ecpg_get_data on line 61: RESULT: 2369.7000000 offset: -1; array: no
|
[NO_PID]: ecpg_get_data on line 61: RESULT: 2369.7000000 offset: -1; array: no
|
||||||
[NO_PID]: sqlca: code: 0, state: 00000
|
[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]: sqlca: code: 0, state: 00000
|
||||||
[NO_PID]: ecpg_finish: connection ecpg1_regression closed
|
[NO_PID]: ecpg_finish: connection ecpg1_regression closed
|
||||||
[NO_PID]: sqlca: code: 0, state: 00000
|
[NO_PID]: sqlca: code: 0, state: 00000
|
||||||
|
@ -4,3 +4,5 @@ sub = 2369.7
|
|||||||
mul = 13306998429.873000000
|
mul = 13306998429.873000000
|
||||||
div = 1330699.84298730000 1.3307e+06
|
div = 1330699.84298730000 1.3307e+06
|
||||||
to long(0) = 20000000 14
|
to long(0) = 20000000 14
|
||||||
|
min int = -2147483648
|
||||||
|
max int = 2147483647
|
||||||
|
@ -19,7 +19,7 @@ main(void)
|
|||||||
exec sql end declare section;
|
exec sql end declare section;
|
||||||
double d;
|
double d;
|
||||||
long l1, l2;
|
long l1, l2;
|
||||||
int i;
|
int i, min, max;
|
||||||
|
|
||||||
ECPGdebug(1, stderr);
|
ECPGdebug(1, stderr);
|
||||||
exec sql whenever sqlerror do sqlprint();
|
exec sql whenever sqlerror do sqlprint();
|
||||||
@ -87,6 +87,17 @@ main(void)
|
|||||||
PGTYPESnumeric_free(value2);
|
PGTYPESnumeric_free(value2);
|
||||||
PGTYPESnumeric_free(res);
|
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 rollback;
|
||||||
exec sql disconnect;
|
exec sql disconnect;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user