Remove arbitrary line length limit for libpq service files.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 22 Sep 2020 19:59:23 +0000 (15:59 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 22 Sep 2020 19:59:23 +0000 (15:59 -0400)
Use a StringInfo instead of a fixed-size buffer in parseServiceInfo().
While we've not heard complaints about the existing 255-byte limit,
it certainly seems possible that complex cases could run afoul of it.

Daniel Gustafsson

Discussion: https://postgr.es/m/48A4FA71-524E-41B9-953A-FD04EF36E2E7@yesql.se

src/interfaces/libpq/fe-connect.c

index 724076a3103e52c363fc366e04fa01360918138a..af27fee6b51e54ddb6188d5435a95e57cddc374e 100644 (file)
@@ -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.
@@ -5099,11 +5098,14 @@ parseServiceFile(const char *serviceFile,
                                 PQExpBuffer errorMessage,
                                 bool *group_found)
 {
-       int                     linenr = 0,
+       int                     result = 0,
+                               linenr = 0,
                                i;
        FILE       *f;
-       char            buf[MAXBUFSIZE],
-                          *line;
+       char       *line;
+       StringInfoData linebuf;
+
+       *group_found = false;
 
        f = fopen(serviceFile, "r");
        if (f == NULL)
@@ -5113,26 +5115,18 @@ parseServiceFile(const char *serviceFile,
                return 1;
        }
 
-       while ((line = fgets(buf, sizeof(buf), f)) != NULL)
-       {
-               int                     len;
+       initStringInfo(&linebuf);
 
+       while (pg_get_line_buf(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';
+
+               line = linebuf.data;
 
                /* ignore leading whitespace too */
                while (*line && isspace((unsigned char) line[0]))
@@ -5147,9 +5141,8 @@ parseServiceFile(const char *serviceFile,
                {
                        if (*group_found)
                        {
-                               /* group info already read */
-                               fclose(f);
-                               return 0;
+                               /* end of desired group reached; return success */
+                               goto exit;
                        }
 
                        if (strncmp(line + 1, service, strlen(service)) == 0 &&
@@ -5178,12 +5171,11 @@ parseServiceFile(const char *serviceFile,
                                        switch (rc)
                                        {
                                                case 0:
-                                                       fclose(f);
-                                                       return 0;
+                                                       goto exit;
                                                case 1:
                                                case 3:
-                                                       fclose(f);
-                                                       return 3;
+                                                       result = 3;
+                                                       goto exit;
                                                case 2:
                                                        continue;
                                        }
@@ -5198,8 +5190,8 @@ parseServiceFile(const char *serviceFile,
                                                                          libpq_gettext("syntax error in service file \"%s\", line %d\n"),
                                                                          serviceFile,
                                                                          linenr);
-                                       fclose(f);
-                                       return 3;
+                                       result = 3;
+                                       goto exit;
                                }
                                *val++ = '\0';
 
@@ -5209,8 +5201,8 @@ parseServiceFile(const char *serviceFile,
                                                                          libpq_gettext("nested service specifications not supported in service file \"%s\", line %d\n"),
                                                                          serviceFile,
                                                                          linenr);
-                                       fclose(f);
-                                       return 3;
+                                       result = 3;
+                                       goto exit;
                                }
 
                                /*
@@ -5228,8 +5220,8 @@ parseServiceFile(const char *serviceFile,
                                                {
                                                        printfPQExpBuffer(errorMessage,
                                                                                          libpq_gettext("out of memory\n"));
-                                                       fclose(f);
-                                                       return 3;
+                                                       result = 3;
+                                                       goto exit;
                                                }
                                                found_keyword = true;
                                                break;
@@ -5242,16 +5234,18 @@ parseServiceFile(const char *serviceFile,
                                                                          libpq_gettext("syntax error in service file \"%s\", line %d\n"),
                                                                          serviceFile,
                                                                          linenr);
-                                       fclose(f);
-                                       return 3;
+                                       result = 3;
+                                       goto exit;
                                }
                        }
                }
        }
 
+exit:
        fclose(f);
+       pfree(linebuf.data);
 
-       return 0;
+       return result;
 }