[PATCH] tar: assume file size of 0 for hardlinks

Ian Wienand ianw at vmware.com
Thu Jul 28 17:29:30 UTC 2011


Hi,

I recently came across a tar file created by an older version of
Python that had a file-size set for a hardlink.  Currently busybox
assumes the file-size is zero but doesn't really check, so
consequently tar skipped ahead and thought the rest of the file was
corrupt.

This is a python bug (a bit of searching found [1]), but as they say
the nice thing about standards is that there are so many choose from.
It appears it is reasonable to just always set this to zero, and then
you can handle these buggy files if need be.

I've attached a small example that currently fails

$ busybox tar tvzf ./foo.tar.gz 
-rw-r--r-- wienandi/mts         6 2011-07-28 10:03:38 foo
-rw-r--r-- wienandi/mts         6 2011-07-28 10:03:38 link-to-foo -> foo
tar: invalid tar header checksum

-i

[1] http://bugs.python.org/issue8833

---
 archival/libarchive/get_header_tar.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c
index f73cd33..96a8281 100644
--- a/archival/libarchive/get_header_tar.c
+++ b/archival/libarchive/get_header_tar.c
@@ -348,12 +348,21 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
 	/* Set bits 12-15 of the files mode */
 	/* (typeflag was not trashed because chksum does not use getOctal) */
 	switch (tar.typeflag) {
-	/* busybox identifies hard links as being regular files with 0 size and a link name */
 	case '1':
 		file_header->mode |= S_IFREG;
-		break;
-	case '7':
-	/* case 0: */
+                /* on size of link fields from star(4)
+                 *   ... For tar archives written by pre POSIX.1-1988
+                 *   implementations, the size field usually contains the size of
+                 *   the file and needs to be ignored as no data may follow this
+                 *   header type.  For POSIX.1- 1988 compliant archives, the size
+                 *   field needs to be 0.  For POSIX.1-2001 compliant archives,
+                 *   the size field may be non zero, indicating that file data is
+                 *   included in the archive.
+                 * i.e; always assume this is zero for saftey
+                 */
+                goto size0;
+        case '7':
+                /* case 0: */
 	case '0':
 #if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY
 		if (last_char_is(file_header->name, '/')) {
-- 
1.7.4.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: foo.tar.gz
Type: application/x-gzip
Size: 188 bytes
Desc: not available
URL: <http://lists.busybox.net/pipermail/busybox/attachments/20110728/4b45e5f6/attachment.bin>


More information about the busybox mailing list