From 9facc585ad28e458239dd6a7df4c204ba1bcf2bc Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 9 Jan 2002 19:13:41 +0000
Subject: [PATCH] Fix use of 'char' to hold result of getc, per bug report
 forwarded by Oliver Elphick.  A few other minor cleanups while at it.

---
 src/backend/libpq/hba.c           | 127 ++++++++++++++----------------
 src/backend/utils/init/miscinit.c | 109 ++++++++++++-------------
 2 files changed, 111 insertions(+), 125 deletions(-)

diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 081fc4977c..80fe645c1a 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.78 2001/11/12 04:29:23 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.79 2002/01/09 19:13:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -111,7 +111,7 @@ next_token(FILE *fp, char *buf, const int bufsz)
 
 
 static void
-read_to_eol(FILE *file)
+read_through_eol(FILE *file)
 {
 	int			c;
 
@@ -162,7 +162,7 @@ tokenize_file(FILE *file)
 		if (comment_ptr != NULL)
 		{
 			/* Found a comment, so skip the rest of the line */
-			read_to_eol(file);
+			read_through_eol(file);
 			next_line = NIL;
 		}
 
@@ -1159,14 +1159,12 @@ GetCharSetByHost(char *TableName, int host, const char *DataDir)
 				OrigCharset[MAX_TOKEN],
 				DestCharset[MAX_TOKEN],
 				HostCharset[MAX_TOKEN],
-				c,
-				eof = false,
 			   *map_file;
-	int			key = 0,
+	int			key,
 				ChIndex = 0,
+				c,
 				i,
 				bufsize;
-
 	struct CharsetItem *ChArray[MAX_CHARSETS];
 
 	*TableName = '\0';
@@ -1174,95 +1172,90 @@ GetCharSetByHost(char *TableName, int host, const char *DataDir)
 	map_file = (char *) palloc(bufsize);
 	snprintf(map_file, bufsize, "%s/%s", DataDir, CHARSET_FILE);
 	file = AllocateFile(map_file, PG_BINARY_R);
+	pfree(map_file);
 	if (file == NULL)
 	{
 		/* XXX should we log a complaint? */
 		return;
 	}
-	while (!eof)
+	while ((c = getc(file)) != EOF)
 	{
-		c = getc(file);
-		ungetc(c, file);
-		if (c == EOF)
-			eof = true;
+		if (c == '#')
+			read_through_eol(file);
 		else
 		{
-			if (c == '#')
-				read_to_eol(file);
-			else
+			/* Read the key */
+			ungetc(c, file);
+			next_token(file, buf, sizeof(buf));
+			if (buf[0] != '\0')
 			{
-				/* Read the key */
-				next_token(file, buf, sizeof(buf));
-				if (buf[0] != '\0')
+				key = 0;
+				if (strcasecmp(buf, "HostCharset") == 0)
+					key = KEY_HOST;
+				if (strcasecmp(buf, "BaseCharset") == 0)
+					key = KEY_BASE;
+				if (strcasecmp(buf, "RecodeTable") == 0)
+					key = KEY_TABLE;
+				switch (key)
 				{
-					if (strcasecmp(buf, "HostCharset") == 0)
-						key = KEY_HOST;
-					if (strcasecmp(buf, "BaseCharset") == 0)
-						key = KEY_BASE;
-					if (strcasecmp(buf, "RecodeTable") == 0)
-						key = KEY_TABLE;
-					switch (key)
-					{
-						case KEY_HOST:
-							/* Read the host */
-							next_token(file, buf, sizeof(buf));
-							if (buf[0] != '\0')
+					case KEY_HOST:
+						/* Read the host */
+						next_token(file, buf, sizeof(buf));
+						if (buf[0] != '\0')
+						{
+							if (CharSetInRange(buf, host))
 							{
-								if (CharSetInRange(buf, host))
-								{
-									/* Read the charset */
-									next_token(file, buf, sizeof(buf));
-									if (buf[0] != '\0')
-										strcpy(HostCharset, buf);
-								}
+								/* Read the charset */
+								next_token(file, buf, sizeof(buf));
+								if (buf[0] != '\0')
+									strcpy(HostCharset, buf);
 							}
-							break;
-						case KEY_BASE:
-							/* Read the base charset */
-							next_token(file, buf, sizeof(buf));
-							if (buf[0] != '\0')
-								strcpy(BaseCharset, buf);
-							break;
-						case KEY_TABLE:
-							/* Read the original charset */
+						}
+						break;
+					case KEY_BASE:
+						/* Read the base charset */
+						next_token(file, buf, sizeof(buf));
+						if (buf[0] != '\0')
+							strcpy(BaseCharset, buf);
+						break;
+					case KEY_TABLE:
+						/* Read the original charset */
+						next_token(file, buf, sizeof(buf));
+						if (buf[0] != '\0')
+						{
+							strcpy(OrigCharset, buf);
+							/* Read the destination charset */
 							next_token(file, buf, sizeof(buf));
 							if (buf[0] != '\0')
 							{
-								strcpy(OrigCharset, buf);
-								/* Read the destination charset */
+								strcpy(DestCharset, buf);
+								/* Read the table filename */
 								next_token(file, buf, sizeof(buf));
 								if (buf[0] != '\0')
 								{
-									strcpy(DestCharset, buf);
-									/* Read the table filename */
-									next_token(file, buf, sizeof(buf));
-									if (buf[0] != '\0')
-									{
-										ChArray[ChIndex] =
-											(struct CharsetItem *) palloc(sizeof(struct CharsetItem));
-										strcpy(ChArray[ChIndex]->Orig, OrigCharset);
-										strcpy(ChArray[ChIndex]->Dest, DestCharset);
-										strcpy(ChArray[ChIndex]->Table, buf);
-										ChIndex++;
-									}
+									ChArray[ChIndex] =
+										(struct CharsetItem *) palloc(sizeof(struct CharsetItem));
+									strcpy(ChArray[ChIndex]->Orig, OrigCharset);
+									strcpy(ChArray[ChIndex]->Dest, DestCharset);
+									strcpy(ChArray[ChIndex]->Table, buf);
+									ChIndex++;
 								}
 							}
-							break;
-					}
-					read_to_eol(file);
+						}
+						break;
 				}
+				read_through_eol(file);
 			}
 		}
 	}
 	FreeFile(file);
-	pfree(map_file);
 
 	for (i = 0; i < ChIndex; i++)
 	{
-		if (!strcasecmp(BaseCharset, ChArray[i]->Orig) &&
-			!strcasecmp(HostCharset, ChArray[i]->Dest))
+		if (strcasecmp(BaseCharset, ChArray[i]->Orig) == 0 &&
+			strcasecmp(HostCharset, ChArray[i]->Dest) == 0)
 			strncpy(TableName, ChArray[i]->Table, 79);
-		pfree((struct CharsetItem *) ChArray[i]);
+		pfree(ChArray[i]);
 	}
 }
 
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 2043fd6a4a..9705dda664 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.81 2001/10/25 05:49:51 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.82 2002/01/09 19:13:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -227,75 +227,80 @@ pg_convert2(PG_FUNCTION_ARGS)
 
 #define MAX_TOKEN	80
 
-/* Some standard C libraries, including GNU, have an isblank() function.
-   Others, including Solaris, do not.  So we have our own.
-*/
+/*
+ * Some standard C libraries, including GNU, have an isblank() function.
+ * Others, including Solaris, do not.  So we have our own.
+ */
 static bool
 isblank(const char c)
 {
-	return c == ' ' || c == 9 /* tab */ ;
+	return c == ' ' || c == '\t';
 }
 
+
+/*
+ *	Grab one token out of fp.  Tokens are strings of non-blank
+ *	characters bounded by blank characters, beginning of line, and end
+ *	of line.	Blank means space or tab.  Return the token as *buf.
+ *	Leave file positioned to character immediately after the token or
+ *	EOF, whichever comes first.  If no more tokens on line, return null
+ *	string as *buf and position file to beginning of next line or EOF,
+ *	whichever comes first.
+ */
 static void
 next_token(FILE *fp, char *buf, const int bufsz)
 {
-/*--------------------------------------------------------------------------
-  Grab one token out of fp.  Tokens are strings of non-blank
-  characters bounded by blank characters, beginning of line, and end
-  of line.	Blank means space or tab.  Return the token as *buf.
-  Leave file positioned to character immediately after the token or
-  EOF, whichever comes first.  If no more tokens on line, return null
-  string as *buf and position file to beginning of next line or EOF,
-  whichever comes first.
---------------------------------------------------------------------------*/
 	int			c;
 	char	   *eb = buf + (bufsz - 1);
 
-	/* Move over inital token-delimiting blanks */
-	while (isblank(c = getc(fp)));
+	/* Move over initial token-delimiting blanks */
+	while ((c = getc(fp)) != EOF && isblank(c))
+		;
 
-	if (c != '\n')
+	if (c != EOF && c != '\n')
 	{
 		/*
 		 * build a token in buf of next characters up to EOF, eol, or
-		 * blank.
+		 * blank.  If the token gets too long, we still parse it
+		 * correctly, but the excess characters are not stored into *buf.
 		 */
 		while (c != EOF && c != '\n' && !isblank(c))
 		{
 			if (buf < eb)
 				*buf++ = c;
 			c = getc(fp);
-
-			/*
-			 * Put back the char right after the token (putting back EOF
-			 * is ok)
-			 */
 		}
-		ungetc(c, fp);
+
+		/*
+		 * Put back the char right after the token (critical in case it is
+		 * eol, since we need to detect end-of-line at next call).
+		 */
+		if (c != EOF)
+			ungetc(c, fp);
 	}
 	*buf = '\0';
 }
 
+
 static void
 read_through_eol(FILE *file)
 {
 	int			c;
 
-	do
-		c = getc(file);
-	while (c != '\n' && c != EOF);
+	while ((c = getc(file)) != EOF && c != '\n')
+		;
 }
 
+
 void
-SetCharSet()
+SetCharSet(void)
 {
 	FILE	   *file;
-	char	   *p,
-				c,
-				eof = false;
+	char	   *p;
 	char	   *map_file;
 	char		buf[MAX_TOKEN];
-	int			i;
+	int			i,
+				c;
 	unsigned char FromChar,
 				ToChar;
 	char		ChTable[80];
@@ -316,49 +321,37 @@ SetCharSet()
 
 	if (p && *p != '\0')
 	{
-		map_file = malloc(strlen(DataDir) + strlen(p) + 2);
-		if (!map_file)
-			elog(FATAL, "out of memory");
+		map_file = palloc(strlen(DataDir) + strlen(p) + 2);
 		sprintf(map_file, "%s/%s", DataDir, p);
 		file = AllocateFile(map_file, PG_BINARY_R);
+		pfree(map_file);
 		if (file == NULL)
-		{
-			free(map_file);
 			return;
-		}
-		eof = false;
-		while (!eof)
+		while ((c = getc(file)) != EOF)
 		{
-			c = getc(file);
-			ungetc(c, file);
-			if (c == EOF)
-				eof = true;
+			if (c == '#')
+				read_through_eol(file);
 			else
 			{
-				if (c == '#')
-					read_through_eol(file);
-				else
+				/* Read the FromChar */
+				ungetc(c, file);
+				next_token(file, buf, sizeof(buf));
+				if (buf[0] != '\0')
 				{
-					/* Read the FromChar */
+					FromChar = strtoul(buf, 0, 0);
+					/* Read the ToChar */
 					next_token(file, buf, sizeof(buf));
 					if (buf[0] != '\0')
 					{
-						FromChar = strtoul(buf, 0, 0);
-						/* Read the ToChar */
-						next_token(file, buf, sizeof(buf));
-						if (buf[0] != '\0')
-						{
-							ToChar = strtoul(buf, 0, 0);
-							RecodeForwTable[FromChar - 128] = ToChar;
-							RecodeBackTable[ToChar - 128] = FromChar;
-						}
+						ToChar = strtoul(buf, 0, 0);
+						RecodeForwTable[FromChar - 128] = ToChar;
+						RecodeBackTable[ToChar - 128] = FromChar;
 						read_through_eol(file);
 					}
 				}
 			}
 		}
 		FreeFile(file);
-		free(map_file);
 	}
 }
 
-- 
2.49.0