mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	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:
		@@ -8648,7 +8648,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>
 | 
			
		||||
 
 | 
			
		||||
@@ -1586,12 +1586,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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user