From 8f16c4ec9484d9d5dc1200b71b4c7cfa4f940695 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Mon, 21 Sep 2020 13:44:41 +0200
Subject: [PATCH] Remove arbitrary line-length in pg_service.conf parsing

Lines in pg_service.conf were limited to 256 bytes, and while there haven't
been reports of this being an issue it seems quite plausible that the day will
come. This follows up on the work done in commits 784b1ba1a2 and 8f8154a50 to
remove hardwired line lenghts in file parsing.
---
 src/interfaces/libpq/fe-connect.c | 50 +++++++++++++++++--------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 724076a310..fc8b668937 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -28,6 +28,7 @@
 #include "fe-auth.h"
 #include "libpq-fe.h"
 #include "libpq-int.h"
+#include "lib/stringinfo.h"
 #include "mb/pg_wchar.h"
 #include "pg_config_paths.h"
 #include "port/pg_bswap.h"
@@ -5011,8 +5012,6 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 
 #endif							/* USE_LDAP */
 
-#define MAXBUFSIZE 256
-
 /*
  * parseServiceInfo: if a service name has been given, look it up and absorb
  * connection options from it into *options.
@@ -5102,8 +5101,8 @@ parseServiceFile(const char *serviceFile,
 	int			linenr = 0,
 				i;
 	FILE	   *f;
-	char		buf[MAXBUFSIZE],
-			   *line;
+	char	   *line;
+	StringInfoData linebuf;
 
 	f = fopen(serviceFile, "r");
 	if (f == NULL)
@@ -5113,34 +5112,28 @@ parseServiceFile(const char *serviceFile,
 		return 1;
 	}
 
-	while ((line = fgets(buf, sizeof(buf), f)) != NULL)
-	{
-		int			len;
+	initStringInfo(&linebuf);
 
+	while (pg_get_line_append(f, &linebuf))
+	{
 		linenr++;
 
-		if (strlen(line) >= sizeof(buf) - 1)
-		{
-			fclose(f);
-			printfPQExpBuffer(errorMessage,
-							  libpq_gettext("line %d too long in service file \"%s\"\n"),
-							  linenr,
-							  serviceFile);
-			return 2;
-		}
-
 		/* ignore whitespace at end of line, especially the newline */
-		len = strlen(line);
-		while (len > 0 && isspace((unsigned char) line[len - 1]))
-			line[--len] = '\0';
+		while (linebuf.len > 0 && isspace((unsigned char) linebuf.data[linebuf.len - 1]))
+			linebuf.data[--linebuf.len] = '\0';
 
 		/* ignore leading whitespace too */
-		while (*line && isspace((unsigned char) line[0]))
-			line++;
+		while (*(linebuf.data + linebuf.cursor) && isspace((unsigned char) linebuf.data[linebuf.cursor]))
+			linebuf.cursor++;
 
 		/* ignore comments and empty lines */
-		if (line[0] == '\0' || line[0] == '#')
+		if (!linebuf.len || linebuf.data[linebuf.cursor] == '#')
+		{
+			resetStringInfo(&linebuf);
 			continue;
+		}
+
+		line = linebuf.data + linebuf.cursor;
 
 		/* Check for right groupname */
 		if (line[0] == '[')
@@ -5149,6 +5142,7 @@ parseServiceFile(const char *serviceFile,
 			{
 				/* group info already read */
 				fclose(f);
+				pfree(linebuf.data);
 				return 0;
 			}
 
@@ -5179,12 +5173,15 @@ parseServiceFile(const char *serviceFile,
 					{
 						case 0:
 							fclose(f);
+							pfree(linebuf.data);
 							return 0;
 						case 1:
 						case 3:
 							fclose(f);
+							pfree(linebuf.data);
 							return 3;
 						case 2:
+							resetStringInfo(&linebuf);
 							continue;
 					}
 				}
@@ -5199,6 +5196,7 @@ parseServiceFile(const char *serviceFile,
 									  serviceFile,
 									  linenr);
 					fclose(f);
+					pfree(linebuf.data);
 					return 3;
 				}
 				*val++ = '\0';
@@ -5210,6 +5208,7 @@ parseServiceFile(const char *serviceFile,
 									  serviceFile,
 									  linenr);
 					fclose(f);
+					pfree(linebuf.data);
 					return 3;
 				}
 
@@ -5229,6 +5228,7 @@ parseServiceFile(const char *serviceFile,
 							printfPQExpBuffer(errorMessage,
 											  libpq_gettext("out of memory\n"));
 							fclose(f);
+							pfree(linebuf.data);
 							return 3;
 						}
 						found_keyword = true;
@@ -5243,13 +5243,17 @@ parseServiceFile(const char *serviceFile,
 									  serviceFile,
 									  linenr);
 					fclose(f);
+					pfree(linebuf.data);
 					return 3;
 				}
 			}
 		}
+
+		resetStringInfo(&linebuf);
 	}
 
 	fclose(f);
+	pfree(linebuf.data);
 
 	return 0;
 }
-- 
2.21.1 (Apple Git-122.3)

