8000 Fix pg_restore to accept POSIX-conformant tar files. · haying/postgres@e067a77 · GitHub
[go: up one dir, main page]

Skip to content

Commit e067a77

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 5ced7dc commit e067a77

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
@@ -873,8 +873,10 @@ _CloseArchive(ArchiveHandle *AH)
873873

874874
tarClose(AH, th);
875875

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

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

10351042
bool
@@ -1043,11 +1050,15 @@ isValidTarHeader(char *header)
10431050
if (sum != chk)
10441051
return false;
10451052

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

10531064
return false;

0 commit comments

Comments
 (0)
0