diff options
Diffstat (limited to 'src/bin')
-rw-r--r-- | src/bin/pg_basebackup/pg_basebackup.c | 22 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_backup_tar.c | 50 |
2 files changed, 26 insertions, 46 deletions
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index 80de8820ff7..8c4dffea936 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -781,7 +781,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) bool in_tarhdr = true; bool skip_file = false; size_t tarhdrsz = 0; - size_t filesz = 0; + pgoff_t filesz = 0; #ifdef HAVE_LIBZ gzFile ztarfile = NULL; @@ -1046,7 +1046,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) skip_file = (strcmp(&tarhdr[0], "recovery.conf") == 0); - sscanf(&tarhdr[124], "%11o", (unsigned int *) &filesz); + filesz = read_tar_number(&tarhdr[124], 12); padding = ((filesz + 511) & ~511) - filesz; filesz += padding; @@ -1139,7 +1139,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) char current_path[MAXPGPATH]; char filename[MAXPGPATH]; const char *mapped_tblspc_path; - int current_len_left; + pgoff_t current_len_left = 0; int current_padding = 0; bool basetablespace; char *copybuf = NULL; @@ -1208,20 +1208,10 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) } totaldone += 512; - if (sscanf(copybuf + 124, "%11o", ¤t_len_left) != 1) - { - fprintf(stderr, _("%s: could not parse file size\n"), - progname); - disconnect_and_exit(1); - } + current_len_left = read_tar_number(©buf[124], 12); /* Set permissions on the file */ - if (sscanf(©buf[100], "%07o ", &filemode) != 1) - { - fprintf(stderr, _("%s: could not parse file mode\n"), - progname); - disconnect_and_exit(1); - } + filemode = read_tar_number(©buf[100], 8); /* * All files are padded up to 512 bytes @@ -2180,7 +2170,7 @@ main(int argc, char **argv) if (replication_slot && !streamwal) { fprintf(stderr, - _("%s: replication slots can only be used with WAL streaming\n"), + _("%s: replication slots can only be used with WAL streaming\n"), progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c index 532eacc066e..c40dfe5726a 100644 --- a/src/bin/pg_dump/pg_backup_tar.c +++ b/src/bin/pg_dump/pg_backup_tar.c @@ -78,13 +78,6 @@ typedef struct ArchiveHandle *AH; } TAR_MEMBER; -/* - * Maximum file size for a tar member: The limit inherent in the - * format is 2^33-1 bytes (nearly 8 GB). But we don't want to exceed - * what we can represent in pgoff_t. - */ -#define MAX_TAR_MEMBER_FILELEN (((int64) 1 << Min(33, sizeof(pgoff_t)*8 - 1)) - 1) - typedef struct { int hasSeek; @@ -1049,7 +1042,7 @@ isValidTarHeader(char *header) int sum; int chk = tarChecksum(header); - sscanf(&header[148], "%8o", &sum); + sum = read_tar_number(&header[148], 8); if (sum != chk) return false; @@ -1091,13 +1084,6 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th) strerror(errno)); fseeko(tmp, 0, SEEK_SET); - /* - * Some compilers will throw a warning knowing this test can never be true - * because pgoff_t can't exceed the compared maximum on their platform. - */ - if (th->fileLen > MAX_TAR_MEMBER_FILELEN) - exit_horribly(modulename, "archive member too large for tar format\n"); - _tarWriteHeader(th); while ((cnt = fread(buf, 1, sizeof(buf), tmp)) > 0) @@ -1222,11 +1208,10 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) { lclContext *ctx = (lclContext *) AH->formatData; char h[512]; - char tag[100]; + char tag[100 + 1]; int sum, chk; - size_t len; - unsigned long ullen; + pgoff_t len; pgoff_t hPos; bool gotBlock = false; @@ -1249,7 +1234,7 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) /* Calc checksum */ chk = tarChecksum(h); - sscanf(&h[148], "%8o", &sum); + sum = read_tar_number(&h[148], 8); /* * If the checksum failed, see if it is a null block. If so, silently @@ -1272,27 +1257,31 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) } } - sscanf(&h[0], "%99s", tag); - sscanf(&h[124], "%12lo", &ullen); - len = (size_t) ullen; + /* Name field is 100 bytes, might not be null-terminated */ + strlcpy(tag, &h[0], 100 + 1); + + len = read_tar_number(&h[124], 12); { - char buf[100]; + char posbuf[32]; + char lenbuf[32]; - snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) hPos); - ahlog(AH, 3, "TOC Entry %s at %s (length %lu, checksum %d)\n", - tag, buf, (unsigned long) len, sum); + snprintf(posbuf, sizeof(posbuf), UINT64_FORMAT, (uint64) hPos); + snprintf(lenbuf, sizeof(lenbuf), UINT64_FORMAT, (uint64) len); + ahlog(AH, 3, "TOC Entry %s at %s (length %s, checksum %d)\n", + tag, posbuf, lenbuf, sum); } if (chk != sum) { - char buf[100]; + char posbuf[32]; - snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) ftello(ctx->tarFH)); + snprintf(posbuf, sizeof(posbuf), UINT64_FORMAT, + (uint64) ftello(ctx->tarFH)); exit_horribly(modulename, "corrupt tar header found in %s " "(expected %d, computed %d) file position %s\n", - tag, sum, chk, buf); + tag, sum, chk, posbuf); } th->targetFile = pg_strdup(tag); @@ -1307,7 +1296,8 @@ _tarWriteHeader(TAR_MEMBER *th) { char h[512]; - tarCreateHeader(h, th->targetFile, NULL, th->fileLen, 0600, 04000, 02000, time(NULL)); + tarCreateHeader(h, th->targetFile, NULL, th->fileLen, + 0600, 04000, 02000, time(NULL)); /* Now write the completed header. */ if (fwrite(h, 1, 512, th->tarFH) != 512) |