Skip to content

Commit e2c9460

Browse files
committed
Fix SortTocFromFile() to cope with lines that are too long for its buffer.
The original coding supposed that a dump TOC file could never contain lines longer than 1K. The folly of that was exposed by a recent report from Per-Olov Esgard. We only really need to see the first dozen or two bytes of each line, since we're just trying to read off the numeric ID at the start of the line; so there's no need for a particularly huge buffer. What there is a need for is logic to not process continuation bufferloads. Back-patch to all supported branches, since it's always been like this.
1 parent 672def6 commit e2c9460

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -992,11 +992,8 @@ SortTocFromFile(Archive *AHX, RestoreOptions *ropt)
992992
{
993993
ArchiveHandle *AH = (ArchiveHandle *) AHX;
994994
FILE *fh;
995-
char buf[1024];
996-
char *cmnt;
997-
char *endptr;
998-
DumpId id;
999-
TocEntry *te;
995+
char buf[100];
996+
bool incomplete_line;
1000997

1001998
/* Allocate space for the 'wanted' array, and init it */
1002999
ropt->idWanted = (bool *) malloc(sizeof(bool) * AH->maxDumpId);
@@ -1008,8 +1005,30 @@ SortTocFromFile(Archive *AHX, RestoreOptions *ropt)
10081005
die_horribly(AH, modulename, "could not open TOC file \"%s\": %s\n",
10091006
ropt->tocFile, strerror(errno));
10101007

1008+
incomplete_line = false;
10111009
while (fgets(buf, sizeof(buf), fh) != NULL)
10121010
{
1011+
bool prev_incomplete_line = incomplete_line;
1012+
int buflen;
1013+
char *cmnt;
1014+
char *endptr;
1015+
DumpId id;
1016+
TocEntry *te;
1017+
1018+
/*
1019+
* Some lines in the file might be longer than sizeof(buf). This is
1020+
* no problem, since we only care about the leading numeric ID which
1021+
* can be at most a few characters; but we have to skip continuation
1022+
* bufferloads when processing a long line.
1023+
*/
1024+
buflen = strlen(buf);
1025+
if (buflen > 0 && buf[buflen - 1] == '\n')
1026+
incomplete_line = false;
1027+
else
1028+
incomplete_line = true;
1029+
if (prev_incomplete_line)
1030+
continue;
1031+
10131032
/* Truncate line at comment, if any */
10141033
cmnt = strchr(buf, ';');
10151034
if (cmnt != NULL)

0 commit comments

Comments
 (0)