diff options
author | Denis Vlasenko | 2008-07-20 17:10:43 +0000 |
---|---|---|
committer | Denis Vlasenko | 2008-07-20 17:10:43 +0000 |
commit | adc772a5f2b5b74f398aaa59c36739fee4ee7a85 (patch) | |
tree | c523a374fd7e9ec52fc935fa84f85dd068723998 /archival | |
parent | b9bbc40f64f305dd09d8f3f31eb5632521f87f0c (diff) | |
download | busybox-adc772a5f2b5b74f398aaa59c36739fee4ee7a85.zip busybox-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.c | 17 | ||||
-rw-r--r-- | archival/libunarchive/seek_by_jump.c | 4 |
2 files changed, 14 insertions, 7 deletions
diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index 7e3c482..e7a3aee 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 031598e..0a259c9 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 |