aboutsummaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-20 17:10:43 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-20 17:10:43 +0000
commitadc772a5f2b5b74f398aaa59c36739fee4ee7a85 (patch)
treec523a374fd7e9ec52fc935fa84f85dd068723998 /archival
parentb9bbc40f64f305dd09d8f3f31eb5632521f87f0c (diff)
downloadbusybox-adc772a5f2b5b74f398aaa59c36739fee4ee7a85.tar.gz
tar: fix handling of tarballs with symlinks with size field != 0
Diffstat (limited to 'archival')
-rw-r--r--archival/libunarchive/get_header_tar.c17
-rw-r--r--archival/libunarchive/seek_by_jump.c4
2 files changed, 14 insertions, 7 deletions
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c
index 7e3c482df..e7a3aeeb3 100644
--- a/archival/libunarchive/get_header_tar.c
+++ b/archival/libunarchive/get_header_tar.c
@@ -266,26 +266,31 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
case '0':
#if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY
if (last_char_is(file_header->name, '/')) {
- file_header->mode |= S_IFDIR;
- } else
+ goto set_dir;
+ }
#endif
file_header->mode |= S_IFREG;
break;
case '2':
file_header->mode |= S_IFLNK;
+ /* have seen tarballs with size field containing
+ * the size of the link target's name */
+ size0:
+ file_header->size = 0;
break;
case '3':
file_header->mode |= S_IFCHR;
- break;
+ goto size0; /* paranoia */
case '4':
file_header->mode |= S_IFBLK;
- break;
+ goto size0;
case '5':
+ set_dir:
file_header->mode |= S_IFDIR;
- break;
+ goto size0;
case '6':
file_header->mode |= S_IFIFO;
- break;
+ goto size0;
#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
case 'L':
/* free: paranoia: tar with several consecutive longnames */
diff --git a/archival/libunarchive/seek_by_jump.c b/archival/libunarchive/seek_by_jump.c
index 031598e7a..0a259c963 100644
--- a/archival/libunarchive/seek_by_jump.c
+++ b/archival/libunarchive/seek_by_jump.c
@@ -8,7 +8,9 @@
void FAST_FUNC seek_by_jump(const archive_handle_t *archive_handle, unsigned amount)
{
- if (lseek(archive_handle->src_fd, (off_t) amount, SEEK_CUR) == (off_t) -1) {
+ if (amount
+ && lseek(archive_handle->src_fd, (off_t) amount, SEEK_CUR) == (off_t) -1
+ ) {
if (errno == ESPIPE)
seek_by_read(archive_handle, amount);
else