From 42f454b13b8d972e85acd7f046065ec69af4d206 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 11 Oct 2019 14:11:44 +0200 Subject: [PATCH] dpkg-deb: work around bogus error message when working with XZ compressed packages function old new delta unpack_xz_stream 2309 2317 +8 bb_full_fd_action 464 472 +8 Signed-off-by: Denys Vlasenko --- archival/libarchive/decompress_unxz.c | 20 +++++++++++++++++++- archival/libarchive/unxz/xz_stream.h | 2 +- libbb/copyfd.c | 13 ++++++++----- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c index f03341384..3dd9bbf49 100644 --- a/archival/libarchive/decompress_unxz.c +++ b/archival/libarchive/decompress_unxz.c @@ -96,6 +96,24 @@ unpack_xz_stream(transformer_state_t *xstate) */ do { if (membuf[iobuf.in_pos] != 0) { + /* There is more data, but is it XZ data? + * Example: dpkg-deb -f busybox_1.30.1-4_amd64.deb + * reads control.tar.xz "control" file + * inside the ar archive, but tar.xz + * extraction code reaches end of xz data, + * reached this code and reads the beginning + * of data.tar.xz's ar header, which isn't xz data, + * and prints "corrupted data". + * The correct solution is to not read + * past nested archive (to simulate EOF). + * This is a workaround: + */ + if (membuf[iobuf.in_pos] != 0xfd) { + /* It's definitely not a xz signature + * (which is 0xfd,"7zXZ",0x00). + */ + goto end; + } xz_dec_reset(state); goto do_run; } @@ -128,7 +146,7 @@ unpack_xz_stream(transformer_state_t *xstate) break; } } - + end: xz_dec_end(state); free(membuf); diff --git a/archival/libarchive/unxz/xz_stream.h b/archival/libarchive/unxz/xz_stream.h index 66cb5a705..45056e42c 100644 --- a/archival/libarchive/unxz/xz_stream.h +++ b/archival/libarchive/unxz/xz_stream.h @@ -25,7 +25,7 @@ #define STREAM_HEADER_SIZE 12 -#define HEADER_MAGIC "\3757zXZ" +#define HEADER_MAGIC "\375""7zXZ" #define HEADER_MAGIC_SIZE 6 #define FOOTER_MAGIC "YZ" diff --git a/libbb/copyfd.c b/libbb/copyfd.c index ae5c26999..d41fd10f0 100644 --- a/libbb/copyfd.c +++ b/libbb/copyfd.c @@ -18,7 +18,7 @@ * was seen to cause largish delays when user tries to ^C a file copy. * Let's use a saner size. * Note: needs to be >= max(CONFIG_FEATURE_COPYBUF_KB), - * or else "copy to eof" code will use neddlesly short reads. + * or else "copy to eof" code will use needlesly short reads. */ #define SENDFILE_BIGBUF (16*1024*1024) @@ -60,10 +60,13 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size) ssize_t rd; if (sendfile_sz) { - rd = sendfile(dst_fd, src_fd, NULL, - size > sendfile_sz ? sendfile_sz : size); - if (rd >= 0) - goto read_ok; + /* dst_fd == -1 is a fake, else... */ + if (dst_fd >= 0) { + rd = sendfile(dst_fd, src_fd, NULL, + size > sendfile_sz ? sendfile_sz : size); + if (rd >= 0) + goto read_ok; + } sendfile_sz = 0; /* do not try sendfile anymore */ } #if CONFIG_FEATURE_COPYBUF_KB > 4 -- 2.25.1