Skip to content

Commit 158cbed

Browse files
committed
Fix pg_restore to accept POSIX-conformant tar files.
Back-patch portions of commit 05b555d. We need to patch pg_restore to accept either version of the magic string, in hopes of avoiding compatibility problems when 9.3 comes out. I also fixed pg_dump to write the correct 2-block EOF marker, since that won't create a compatibility problem with pg_restore and it could help with some versions of tar. Brian Weaver and Tom Lane
1 parent cf78eb4 commit 158cbed

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

src/bin/pg_dump/pg_backup_tar.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -872,8 +872,10 @@ _CloseArchive(ArchiveHandle *AH)
872872

873873
tarClose(AH, th);
874874

875-
/* Add a block of NULLs since it's de-rigeur. */
876-
for (i = 0; i < 512; i++)
875+
/*
876+
* EOF marker for tar files is two blocks of NULLs.
877+
*/
878+
for (i = 0; i < 512 * 2; i++)
877879
{
878880
if (fputc(0, ctx->tarFH) == EOF)
879881
die_horribly(AH, modulename,
@@ -1024,11 +1026,16 @@ _tarChecksum(char *header)
10241026
int i,
10251027
sum;
10261028

1027-
sum = 0;
1029+
/*
1030+
* Per POSIX, the checksum is the simple sum of all bytes in the header,
1031+
* treating the bytes as unsigned, and treating the checksum field (at
1032+
* offset 148) as though it contained 8 spaces.
1033+
*/
1034+
sum = 8 * ' '; /* presumed value for checksum field */
10281035
for (i = 0; i < 512; i++)
10291036
if (i < 148 || i >= 156)
10301037
sum += 0xFF & header[i];
1031-
return sum + 256; /* Assume 8 blanks in checksum field */
1038+
return sum;
10321039
}
10331040

10341041
bool
@@ -1042,11 +1049,15 @@ isValidTarHeader(char *header)
10421049
if (sum != chk)
10431050
return false;
10441051

1045-
/* POSIX format */
1046-
if (strncmp(&header[257], "ustar00", 7) == 0)
1052+
/* POSIX tar format */
1053+
if (memcmp(&header[257], "ustar\0", 6) == 0 &&
1054+
memcmp(&header[263], "00", 2) == 0)
1055+
return true;
1056+
/* GNU tar format */
1057+
if (memcmp(&header[257], "ustar \0", 8) == 0)
10471058
return true;
1048-
/* older format */
1049-
if (strncmp(&header[257], "ustar ", 7) == 0)
1059+
/* not-quite-POSIX format written by pre-9.3 pg_dump */
1060+
if (memcmp(&header[257], "ustar00\0", 8) == 0)
10501061
return true;
10511062

10521063
return false;

0 commit comments

Comments
 (0)