Skip to content

Commit f051b87

Browse files
committed
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
1 parent 99da905 commit f051b87

File tree

6 files changed

+38
-9
lines changed

6 files changed

+38
-9
lines changed

doc/src/sgml/ecpg.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8881,7 +8881,7 @@ int dectoint(decimal *np, int *ip);
88818881
Note that the ECPG implementation differs from the <productname>Informix</productname>
88828882
implementation. <productname>Informix</productname> limits an integer to the range from -32767 to
88838883
32767, while the limits in the ECPG implementation depend on the
8884-
architecture (<literal>-INT_MAX .. INT_MAX</literal>).
8884+
architecture (<literal>INT_MIN .. INT_MAX</literal>).
88858885
</para>
88868886
</listitem>
88878887
</varlistentry>

src/interfaces/ecpg/pgtypeslib/numeric.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1505,12 +1505,17 @@ PGTYPESnumeric_to_int(numeric *nv, int *ip)
15051505
if ((i = PGTYPESnumeric_to_long(nv, &l)) != 0)
15061506
return i;
15071507

1508-
if (l < -INT_MAX || l > INT_MAX)
1508+
/* silence compilers that might complain about useless tests */
1509+
#if SIZEOF_LONG > SIZEOF_INT
1510+
1511+
if (l < INT_MIN || l > INT_MAX)
15091512
{
15101513
errno = PGTYPES_NUM_OVERFLOW;
15111514
return -1;
15121515
}
15131516

1517+
#endif
1518+
15141519
*ip = (int) l;
15151520
return 0;
15161521
}

src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ main(void)
7575

7676
double d;
7777
long l1, l2;
78-
int i;
78+
int i, min, max;
7979

8080
ECPGdebug(1, stderr);
8181
/* exec sql whenever sqlerror do sqlprint ( ) ; */
@@ -174,17 +174,28 @@ if (sqlca.sqlcode < 0) sqlprint ( );}
174174
PGTYPESnumeric_free(value2);
175175
PGTYPESnumeric_free(res);
176176

177+
/* check conversion of numeric to int */
178+
value1 = PGTYPESnumeric_from_asc("-2147483648", NULL);
179+
PGTYPESnumeric_to_int(value1, &min);
180+
printf("min int = %d\n", min);
181+
PGTYPESnumeric_free(value1);
182+
183+
value2 = PGTYPESnumeric_from_asc("2147483647", NULL);
184+
PGTYPESnumeric_to_int(value2, &max);
185+
printf("max int = %d\n", max);
186+
PGTYPESnumeric_free(value2);
187+
177188
{ ECPGtrans(__LINE__, NULL, "rollback");
178-
#line 90 "num_test.pgc"
189+
#line 101 "num_test.pgc"
179190

180191
if (sqlca.sqlcode < 0) sqlprint ( );}
181-
#line 90 "num_test.pgc"
192+
#line 101 "num_test.pgc"
182193

183194
{ ECPGdisconnect(__LINE__, "CURRENT");
184-
#line 91 "num_test.pgc"
195+
#line 102 "num_test.pgc"
185196

186197
if (sqlca.sqlcode < 0) sqlprint ( );}
187-
#line 91 "num_test.pgc"
198+
#line 102 "num_test.pgc"
188199

189200

190201
return 0;

src/interfaces/ecpg/test/expected/pgtypeslib-num_test.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
[NO_PID]: sqlca: code: 0, state: 00000
2727
[NO_PID]: ecpg_get_data on line 61: RESULT: 2369.7000000 offset: -1; array: no
2828
[NO_PID]: sqlca: code: 0, state: 00000
29-
[NO_PID]: ECPGtrans on line 90: action "rollback"; connection "ecpg1_regression"
29+
[NO_PID]: ECPGtrans on line 101: action "rollback"; connection "ecpg1_regression"
3030
[NO_PID]: sqlca: code: 0, state: 00000
3131
[NO_PID]: ecpg_finish: connection ecpg1_regression closed
3232
[NO_PID]: sqlca: code: 0, state: 00000

src/interfaces/ecpg/test/expected/pgtypeslib-num_test.stdout

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ sub = 2369.7
44
mul = 13306998429.873000000
55
div = 1330699.84298730000 1.3307e+06
66
to long(0) = 20000000 14
7+
min int = -2147483648
8+
max int = 2147483647

src/interfaces/ecpg/test/pgtypeslib/num_test.pgc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ main(void)
1919
exec sql end declare section;
2020
double d;
2121
long l1, l2;
22-
int i;
22+
int i, min, max;
2323

2424
ECPGdebug(1, stderr);
2525
exec sql whenever sqlerror do sqlprint();
@@ -87,6 +87,17 @@ main(void)
8787
PGTYPESnumeric_free(value2);
8888
PGTYPESnumeric_free(res);
8989

90+
/* check conversion of numeric to int */
91+
value1 = PGTYPESnumeric_from_asc("-2147483648", NULL);
92+
PGTYPESnumeric_to_int(value1, &min);
93+
printf("min int = %d\n", min);
94+
PGTYPESnumeric_free(value1);
95+
96+
value2 = PGTYPESnumeric_from_asc("2147483647", NULL);
97+
PGTYPESnumeric_to_int(value2, &max);
98+
printf("max int = %d\n", max);
99+
PGTYPESnumeric_free(value2);
100+
90101
exec sql rollback;
91102
exec sql disconnect;
92103

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy