Re: Fix for Win32 division involving INT_MIN - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: Fix for Win32 division involving INT_MIN
Date
Msg-id 200606090240.k592eUj23952@candle.pha.pa.us
Whole thread Raw
In response to Re: Fix for Win32 division involving INT_MIN  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Fix for Win32 division involving INT_MIN  (Bruce Momjian <pgman@candle.pha.pa.us>)
List pgsql-patches
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > With no Win32 exception detection code in sight, I propose the following
> > patch to prevent server crashes for unusual INT_MIN integer division.
>
> The overflow code tries hard to avoid assuming it knows what INT_MIN and
> INT_MAX are --- this is maybe not so important for int4 but it is for
> int8 (because of our support for int8-less machines).  I don't
> immediately see how to make this test without assuming you know the
> value of INT_MIN, but we ought to try to come up with one.
>
> We do see funny behavior on Intel chips even without Windows, so it'd
> be better to not #ifdef WIN32 but use the same overflow test for
> everyone.

> I would imagine the same problem arises with int8, has anyone checked?

Seems int8 is OK on Win32:

    postgres=# SELECT (-9223372036854775808) / (-1);
    ERROR:  bigint out of range

> Also, the overflow tests in the intNmul routines seem vulnerable.

I reproduced the crash using int4 multiplication.  Again int8
multiplication seemed OK.

I tried int2 and that seemed OK.

Updated patch attached.

--
  Bruce Momjian   http://candle.pha.pa.us
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +
Index: src/backend/utils/adt/int.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/int.c,v
retrieving revision 1.72
diff -c -c -r1.72 int.c
*** src/backend/utils/adt/int.c    11 Mar 2006 01:19:22 -0000    1.72
--- src/backend/utils/adt/int.c    9 Jun 2006 02:36:32 -0000
***************
*** 735,740 ****
--- 735,751 ----
      int32        arg2 = PG_GETARG_INT32(1);
      int32        result;

+ #ifdef WIN32
+     /*
+      *    Win32 doesn't throw a catchable exception for
+      *    SELECT -2147483648 /* INT_MIN */ * (-1);
+      */
+     if (arg2 == -1 && arg1 == INT_MIN)
+         ereport(ERROR,
+                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+                  errmsg("integer out of range")));
+ #endif
+
      result = arg1 * arg2;

      /*
***************
*** 770,775 ****
--- 781,797 ----
                  (errcode(ERRCODE_DIVISION_BY_ZERO),
                   errmsg("division by zero")));

+ #ifdef WIN32
+     /*
+      *    Win32 doesn't throw a catchable exception for
+      *    SELECT -2147483648 /* INT_MIN */ / (-1);
+      */
+     if (arg2 == -1 && arg1 == INT_MIN)
+         ereport(ERROR,
+                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+                  errmsg("integer out of range")));
+ #endif
+
      result = arg1 / arg2;

      /*

pgsql-patches by date:

Previous
From: Tom Lane
Date:
Subject: Re: Fix for Win32 division involving INT_MIN
Next
From: Dhanaraj M
Date:
Subject: Re: Patch for - Allow server logs to be remotely read