From b32cac8055118d264b27b1073d3d43e9a127130e Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Thu, 22 Mar 2001 17:41:47 +0000 Subject: [PATCH] Fix Joubert's complaint that int8-sized numeric literals are mishandled 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 | 16 +++++++++++----- src/backend/parser/scan.l | 24 +++++++++++++++++++----- src/backend/utils/misc/guc.c | 9 +++++++-- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c index 1f41cc85718..14a492b4768 100644 --- a/src/backend/nodes/read.c +++ b/src/backend/nodes/read.c @@ -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; } diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index f913584c1a7..0f876e7718c 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -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} { diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index feceb5d9500..1d779979a19 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -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 <peter_e@gmx.net>. @@ -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; -- GitLab