Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1471a14

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 82a4f37 commit 1471a14

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

src/bin/pg_dump/pg_backup_archiver.c

+24-5
Original file line numberDiff line numberDiff line change
@@ -1003,11 +1003,8 @@ SortTocFromFile(Archive *AHX, RestoreOptions *ropt)
10031003
{
10041004
ArchiveHandle *AH = (ArchiveHandle *) AHX;
10051005
FILE *fh;
1006-
char buf[1024];
1007-
char *cmnt;
1008-
char *endptr;
1009-
DumpId id;
1010-
TocEntry *te;
1006+
char buf[100];
1007+
bool incomplete_line;
10111008

10121009
/* Allocate space for the 'wanted' array, and init it */
10131010
ropt->idWanted = (bool *) malloc(sizeof(bool) * AH->maxDumpId);
@@ -1019,8 +1016,30 @@ SortTocFromFile(Archive *AHX, RestoreOptions *ropt)
10191016
die_horribly(AH, modulename, "could not open TOC file \"%s\": %s\n",
10201017
ropt->tocFile, strerror(errno));
10211018

1019+
incomplete_line = false;
10221020
while (fgets(buf, sizeof(buf), fh) != NULL)
10231021
{
1022+
bool prev_incomplete_line = incomplete_line;
1023+
int buflen;
1024+
char *cmnt;
1025+
char *endptr;
1026+
DumpId id;
1027+
TocEntry *te;
1028+
1029+
/*
1030+
* Some lines in the file might be longer than sizeof(buf). This is
1031+
* no problem, since we only care about the leading numeric ID which
1032+
* can be at most a few characters; but we have to skip continuation
1033+
* bufferloads when processing a long line.
1034+
*/
1035+
buflen = strlen(buf);
1036+
if (buflen > 0 && buf[buflen - 1] == '\n')
1037+
incomplete_line = false;
1038+
else
1039+
incomplete_line = true;
1040+
if (prev_incomplete_line)
1041+
continue;
1042+
10241043
/* Truncate line at comment, if any */
10251044
cmnt = strchr(buf, ';');
10261045
if (cmnt != NULL)

0 commit comments

Comments
 (0)