aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-09-22 16:03:32 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-09-22 16:03:32 -0400
commit2e3c19462da930d1d018caa3daabca00159b4b18 (patch)
tree8046f06e968e47c2734b8d66ae16e8779305a070 /src
parentc0cb87fbb6642222a99593785f77d318af06ef02 (diff)
downloadpostgresql-2e3c19462da930d1d018caa3daabca00159b4b18.tar.gz
postgresql-2e3c19462da930d1d018caa3daabca00159b4b18.zip
Simplify SortTocFromFile() by removing fixed buffer-size limit.
pg_restore previously coped with overlength TOC-file lines using some complicated logic to ignore additional bufferloads. While this isn't wrong, since we don't expect that the interesting part of a line would run to more than a dozen or so bytes, it's more complex than it needs to be. Use a StringInfo instead of a fixed-size buffer so that we can process long lines as single entities and thus not need the extra logic. Daniel Gustafsson Discussion: https://postgr.es/m/48A4FA71-524E-41B9-953A-FD04EF36E2E7@yesql.se
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.c41
1 files changed, 16 insertions, 25 deletions
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index bc475782943..3567e9f365f 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -30,8 +30,10 @@
#include <io.h>
#endif
+#include "common/string.h"
#include "dumputils.h"
#include "fe_utils/string_utils.h"
+#include "lib/stringinfo.h"
#include "libpq/libpq-fs.h"
#include "parallel.h"
#include "pg_backup_archiver.h"
@@ -1367,8 +1369,7 @@ SortTocFromFile(Archive *AHX)
ArchiveHandle *AH = (ArchiveHandle *) AHX;
RestoreOptions *ropt = AH->public.ropt;
FILE *fh;
- char buf[100];
- bool incomplete_line;
+ StringInfoData linebuf;
/* Allocate space for the 'wanted' array, and init it */
ropt->idWanted = (bool *) pg_malloc0(sizeof(bool) * AH->maxDumpId);
@@ -1378,45 +1379,33 @@ SortTocFromFile(Archive *AHX)
if (!fh)
fatal("could not open TOC file \"%s\": %m", ropt->tocFile);
- incomplete_line = false;
- while (fgets(buf, sizeof(buf), fh) != NULL)
+ initStringInfo(&linebuf);
+
+ while (pg_get_line_buf(fh, &linebuf))
{
- bool prev_incomplete_line = incomplete_line;
- int buflen;
char *cmnt;
char *endptr;
DumpId id;
TocEntry *te;
- /*
- * Some lines in the file might be longer than sizeof(buf). This is
- * no problem, since we only care about the leading numeric ID which
- * can be at most a few characters; but we have to skip continuation
- * bufferloads when processing a long line.
- */
- buflen = strlen(buf);
- if (buflen > 0 && buf[buflen - 1] == '\n')
- incomplete_line = false;
- else
- incomplete_line = true;
- if (prev_incomplete_line)
- continue;
-
/* Truncate line at comment, if any */
- cmnt = strchr(buf, ';');
+ cmnt = strchr(linebuf.data, ';');
if (cmnt != NULL)
+ {
cmnt[0] = '\0';
+ linebuf.len = cmnt - linebuf.data;
+ }
/* Ignore if all blank */
- if (strspn(buf, " \t\r\n") == strlen(buf))
+ if (strspn(linebuf.data, " \t\r\n") == linebuf.len)
continue;
/* Get an ID, check it's valid and not already seen */
- id = strtol(buf, &endptr, 10);
- if (endptr == buf || id <= 0 || id > AH->maxDumpId ||
+ id = strtol(linebuf.data, &endptr, 10);
+ if (endptr == linebuf.data || id <= 0 || id > AH->maxDumpId ||
ropt->idWanted[id - 1])
{
- pg_log_warning("line ignored: %s", buf);
+ pg_log_warning("line ignored: %s", linebuf.data);
continue;
}
@@ -1443,6 +1432,8 @@ SortTocFromFile(Archive *AHX)
_moveBefore(AH->toc, te);
}
+ pg_free(linebuf.data);
+
if (fclose(fh) != 0)
fatal("could not close TOC file: %m");
}