Skip to content

Commit 2e3c194

Browse files
committed
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
1 parent c0cb87f commit 2e3c194

File tree

1 file changed

+16
-25
lines changed

1 file changed

+16
-25
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@
3030
#include <io.h>
3131
#endif
3232

33+
#include "common/string.h"
3334
#include "dumputils.h"
3435
#include "fe_utils/string_utils.h"
36+
#include "lib/stringinfo.h"
3537
#include "libpq/libpq-fs.h"
3638
#include "parallel.h"
3739
#include "pg_backup_archiver.h"
@@ -1367,8 +1369,7 @@ SortTocFromFile(Archive *AHX)
13671369
ArchiveHandle *AH = (ArchiveHandle *) AHX;
13681370
RestoreOptions *ropt = AH->public.ropt;
13691371
FILE *fh;
1370-
char buf[100];
1371-
bool incomplete_line;
1372+
StringInfoData linebuf;
13721373

13731374
/* Allocate space for the 'wanted' array, and init it */
13741375
ropt->idWanted = (bool *) pg_malloc0(sizeof(bool) * AH->maxDumpId);
@@ -1378,45 +1379,33 @@ SortTocFromFile(Archive *AHX)
13781379
if (!fh)
13791380
fatal("could not open TOC file \"%s\": %m", ropt->tocFile);
13801381

1381-
incomplete_line = false;
1382-
while (fgets(buf, sizeof(buf), fh) != NULL)
1382+
initStringInfo(&linebuf);
1383+
1384+
while (pg_get_line_buf(fh, &linebuf))
13831385
{
1384-
bool prev_incomplete_line = incomplete_line;
1385-
int buflen;
13861386
char *cmnt;
13871387
char *endptr;
13881388
DumpId id;
13891389
TocEntry *te;
13901390

1391-
/*
1392-
* Some lines in the file might be longer than sizeof(buf). This is
1393-
* no problem, since we only care about the leading numeric ID which
1394-
* can be at most a few characters; but we have to skip continuation
1395-
* bufferloads when processing a long line.
1396-
*/
1397-
buflen = strlen(buf);
1398-
if (buflen > 0 && buf[buflen - 1] == '\n')
1399-
incomplete_line = false;
1400-
else
1401-
incomplete_line = true;
1402-
if (prev_incomplete_line)
1403-
continue;
1404-
14051391
/* Truncate line at comment, if any */
1406-
cmnt = strchr(buf, ';');
1392+
cmnt = strchr(linebuf.data, ';');
14071393
if (cmnt != NULL)
1394+
{
14081395
cmnt[0] = '\0';
1396+
linebuf.len = cmnt - linebuf.data;
1397+
}
14091398

14101399
/* Ignore if all blank */
1411-
if (strspn(buf, " \t\r\n") == strlen(buf))
1400+
if (strspn(linebuf.data, " \t\r\n") == linebuf.len)
14121401
continue;
14131402

14141403
/* Get an ID, check it's valid and not already seen */
1415-
id = strtol(buf, &endptr, 10);
1416-
if (endptr == buf || id <= 0 || id > AH->maxDumpId ||
1404+
id = strtol(linebuf.data, &endptr, 10);
1405+
if (endptr == linebuf.data || id <= 0 || id > AH->maxDumpId ||
14171406
ropt->idWanted[id - 1])
14181407
{
1419-
pg_log_warning("line ignored: %s", buf);
1408+
pg_log_warning("line ignored: %s", linebuf.data);
14201409
continue;
14211410
}
14221411

@@ -1443,6 +1432,8 @@ SortTocFromFile(Archive *AHX)
14431432
_moveBefore(AH->toc, te);
14441433
}
14451434

1435+
pg_free(linebuf.data);
1436+
14461437
if (fclose(fh) != 0)
14471438
fatal("could not close TOC file: %m");
14481439
}

0 commit comments

Comments
 (0)