]> 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:34:33 +0000 (16:34 -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 27534872dee311f2185146103923192f7eede2ef..41a5032c5e11231cd65c6db0c16d0a9ca0e76916 100644 (file)
@@ -8575,7 +8575,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</>).
+        architecture (<literal>INT_MIN .. INT_MAX</>).
        </para>
       </listitem>
      </varlistentry>
index a93d074de211bc5e9cbae519695ba1e9c6db35e8..c9c1a3896d3b40a4d503eb8262952cc5667024fe 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 6dad1dc4e4d117e2db4aa6610a0a6cbda398d6b0..0da155dfd8e544891ec304e4215bed58bd1fa765 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 0b5de558eba46293a6d66dbe6b6b18a59866898d..94379cfbf024a6cc6a780fad43083be027edf98f 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;