]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix range check in ECPG numeric to int conversion
authorJohn Naylor <john.naylor@postgresql.org>
Fri, 30 Jul 2021 17:50:23 +0000 (13:50 -0400)
committerJohn Naylor <john.naylor@postgresql.org>
Fri, 30 Jul 2021 20:12:17 +0000 (16:12 -0400)
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

doc/src/sgml/ecpg.sgml
src/interfaces/ecpg/pgtypeslib/numeric.c
src/interfaces/ecpg/test/expected/pgtypeslib-num_test.c
src/interfaces/ecpg/test/expected/pgtypeslib-num_test.stderr
src/interfaces/ecpg/test/expected/pgtypeslib-num_test.stdout
src/interfaces/ecpg/test/pgtypeslib/num_test.pgc

index b4e69664057885dc3f7fa770d41bca23419c2ee5..e94073f461d93d12f3c0f9cef4ba2186dd637078 100644 (file)
@@ -8618,7 +8618,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>
index 6643242ab196ba98f5c2ad31d3ef88f353135a49..88a4302faa67049fea3a51fced0d6cfdd76c4708 100644 (file)
@@ -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;
 }
index 1b1239eacad48354f9a857a94abc3c350a270fa9..43d1e15c17cc6dfce74b503a29301d3406d40e4a 100644 (file)
@@ -47,7 +47,7 @@ main(void)
 
        double d;
        long l1, l2;
-       int i;
+       int i, min, max;
 
        ECPGdebug(1, stderr);
        /* exec sql whenever sqlerror  do sqlprint ( ) ; */
@@ -144,17 +144,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 93 "num_test.pgc"
+#line 104 "num_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
-#line 93 "num_test.pgc"
+#line 104 "num_test.pgc"
 
        { ECPGdisconnect(__LINE__, "CURRENT");
-#line 94 "num_test.pgc"
+#line 105 "num_test.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint ( );}
-#line 94 "num_test.pgc"
+#line 105 "num_test.pgc"
 
 
        return 0;
index d834c22aab9218b51016d99e529316a13574a148..c57fe8b7a907c6f9c3b7e8447e6d891c9e765c94 100644 (file)
@@ -26,7 +26,7 @@
 [NO_PID]: sqlca: code: 0, state: 00000
 [NO_PID]: ecpg_get_data on line 66: RESULT: 2369.7000000 offset: -1; array: no
 [NO_PID]: sqlca: code: 0, state: 00000
-[NO_PID]: ECPGtrans on line 93: action "rollback"; connection "ecpg1_regression"
+[NO_PID]: ECPGtrans on line 104: 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
index 52515ebde268e1c082f6e525a04d161036de6d24..459d4bffd837630901cba0548a2bbb5d12e6cbf7 100644 (file)
@@ -4,3 +4,5 @@ sub = 2369.7
 mul = 13306998429.873000000
 div = 1330699.84298730000 1.330700e+06
 to long(0) = 20000000 14
+min int = -2147483648
+max int = 2147483647
index 98912704947acb69e5bd39cd0c0efe462ce007e9..7bdd375df13996b337fdc5c29ea496609b0587e9 100644 (file)
@@ -24,7 +24,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();
@@ -90,6 +90,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;