Fix Joubert's complaint that int8-sized numeric literals are mishandled
authorTom Lane <[email protected]>
Thu, 22 Mar 2001 17:41:47 +0000 (17:41 +0000)
committerTom Lane <[email protected]>
Thu, 22 Mar 2001 17:41:47 +0000 (17:41 +0000)
on Alpha (because parser mistakenly assumes that a nonoverflow result
from strtol means the value will fit into int4).  A scan for other uses
of strtol and strtoul found a couple other places with the same mistake;
fix them too.  The changes are all conditional on HAVE_LONG_INT_64 to
avoid complaints from compilers that think x != x is a silly test
(cf. pg_atoi).

src/backend/nodes/read.c
src/backend/parser/scan.l
src/backend/utils/misc/guc.c

index 1f41cc85718b1c97a881af09802df20ea2d47338..14a492b476810bb24fd3dcc74bb6a9fa7844d258 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.29 2001/03/22 03:59:32 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.30 2001/03/22 17:41:47 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -203,7 +203,6 @@ nodeTokenType(char *token, int length)
        NodeTag         retval;
        char       *numptr;
        int                     numlen;
-       char       *endptr;
 
        /*
         * Check if the token is a number
@@ -215,16 +214,23 @@ nodeTokenType(char *token, int length)
        if ((numlen > 0 && isdigit((unsigned char) *numptr)) ||
        (numlen > 1 && *numptr == '.' && isdigit((unsigned char) numptr[1])))
        {
-
                /*
                 * Yes.  Figure out whether it is integral or float; this requires
                 * both a syntax check and a range check. strtol() can do both for
                 * us. We know the token will end at a character that strtol will
                 * stop at, so we do not need to modify the string.
                 */
+               long    val;
+               char   *endptr;
+
                errno = 0;
-               (void) strtol(token, &endptr, 10);
-               if (endptr != token + length || errno == ERANGE)
+               val = strtol(token, &endptr, 10);
+               if (endptr != token + length || errno == ERANGE
+#ifdef HAVE_LONG_INT_64
+                       /* if long > 32 bits, check for overflow of int4 */
+                       || val != (long) ((int32) val)
+#endif
+                  )
                        return T_Float;
                return T_Integer;
        }
index f913584c1a77e91972c5146ce09aa8b96ceac069..0f876e7718c2c680862b2ef5894d0032751e9739 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.87 2001/02/21 18:53:47 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.88 2001/03/22 17:41:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -310,14 +310,21 @@ other                     .
                                        startlit();
                                }
 <xh>{xhstop}   {
+                                       long val;
                                        char* endptr;
 
                                        BEGIN(INITIAL);
                                        errno = 0;
-                                       yylval.ival = strtol(literalbuf, &endptr, 16);
-                                       if (*endptr != '\0' || errno == ERANGE)
+                                       val = strtol(literalbuf, &endptr, 16);
+                                       if (*endptr != '\0' || errno == ERANGE
+#ifdef HAVE_LONG_INT_64
+                                               /* if long > 32 bits, check for overflow of int4 */
+                                               || val != (long) ((int32) val)
+#endif
+                                               )
                                                elog(ERROR, "Bad hexadecimal integer input '%s'",
                                                         literalbuf);
+                                       yylval.ival = val;
                                        return ICONST;
                                }
 <xh><<EOF>>            { elog(ERROR, "Unterminated hexadecimal integer"); }
@@ -454,16 +461,23 @@ other                     .
                                }
 
 {integer}              {
+                                       long val;
                                        char* endptr;
 
                                        errno = 0;
-                                       yylval.ival = strtol((char *)yytext, &endptr, 10);
-                                       if (*endptr != '\0' || errno == ERANGE)
+                                       val = strtol((char *)yytext, &endptr, 10);
+                                       if (*endptr != '\0' || errno == ERANGE
+#ifdef HAVE_LONG_INT_64
+                                               /* if long > 32 bits, check for overflow of int4 */
+                                               || val != (long) ((int32) val)
+#endif
+                                               )
                                        {
                                                /* integer too large, treat it as a float */
                                                yylval.str = pstrdup((char*)yytext);
                                                return FCONST;
                                        }
+                                       yylval.ival = val;
                                        return ICONST;
                                }
 {decimal}              {
index feceb5d95002edf24e9e359ea8f5413fdfe07513..1d779979a194f92584d2597d3abccf3d97ad22fc 100644 (file)
@@ -4,7 +4,7 @@
  * Support for grand unified configuration scheme, including SET
  * command, configuration file, and command line options.
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.34 2001/03/22 04:00:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.35 2001/03/22 17:41:47 tgl Exp $
  *
  * Copyright 2000 by PostgreSQL Global Development Group
  * Written by Peter Eisentraut <[email protected]>.
@@ -520,7 +520,12 @@ parse_int(const char *value, int *result)
 
        errno = 0;
        val = strtol(value, &endptr, 0);
-       if (endptr == value || *endptr != '\0' || errno == ERANGE)
+       if (endptr == value || *endptr != '\0' || errno == ERANGE
+#ifdef HAVE_LONG_INT_64
+               /* if long > 32 bits, check for overflow of int4 */
+               || val != (long) ((int32) val)
+#endif
+          )
                return false;
        if (result)
                *result = (int) val;