From 45f66167fe96de219aac91d842f3e64d857340f6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 1 Jul 2010 05:12:28 +0200 Subject: [PATCH] xz compression detection: avoid the need to seek function old new delta unpack_unxz 12 67 +55 unpack_xz_stream 2357 2373 +16 xmalloc_read 197 199 +2 setup_unzip_on_fd 118 99 -19 rpm2cpio_main 222 203 -19 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/2 up/down: 73/-38) Total: 35 bytes Signed-off-by: Denys Vlasenko --- archival/bbunzip.c | 9 +++++++++ archival/libunarchive/decompress_unxz.c | 4 +++- archival/rpm2cpio.c | 4 ++-- include/unarchive.h | 23 ++++++++++++++--------- libbb/read_printf.c | 4 ++-- 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/archival/bbunzip.c b/archival/bbunzip.c index b243afb2e..832a7bbf3 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -373,6 +373,15 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) static IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(unpack_info_t *info UNUSED_PARAM) { + struct { + uint32_t v1; + uint16_t v2; + } magic; + xread(STDIN_FILENO, &magic, 6); + if (magic.v1 != XZ_MAGIC1a || magic.v2 != XZ_MAGIC2a) { + bb_error_msg("invalid magic"); + return -1; + } return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO); } int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; diff --git a/archival/libunarchive/decompress_unxz.c b/archival/libunarchive/decompress_unxz.c index 5d7513a2e..721acd907 100644 --- a/archival/libunarchive/decompress_unxz.c +++ b/archival/libunarchive/decompress_unxz.c @@ -56,9 +56,11 @@ unpack_xz_stream(int src_fd, int dst_fd) if (!crc32_table) crc32_table = crc32_filltable(NULL, /*endian:*/ 0); - membuf = xmalloc(2 * BUFSIZ); memset(&iobuf, 0, sizeof(iobuf)); + /* Preload XZ file signature */ + membuf = (void*) strcpy(xmalloc(2 * BUFSIZ), HEADER_MAGIC); iobuf.in = membuf; + iobuf.in_size = HEADER_MAGIC_SIZE; iobuf.out = membuf + BUFSIZ; iobuf.out_size = BUFSIZ; diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index 1f67fa887..b23d5afa9 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c @@ -92,8 +92,8 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) xread(rpm_fd, magic.b32, sizeof(magic.b32[0])); if (magic.b32[0] != XZ_MAGIC2) goto no_magic; - /* unpack_xz_stream wants fd at position 0 */ - xlseek(rpm_fd, -6, SEEK_CUR); + /* unpack_xz_stream wants fd at position 6, no need to seek */ + //xlseek(rpm_fd, -6, SEEK_CUR); unpack = unpack_xz_stream; } else { no_magic: diff --git a/include/unarchive.h b/include/unarchive.h index b4cf16082..3b8e1575a 100644 --- a/include/unarchive.h +++ b/include/unarchive.h @@ -7,16 +7,21 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN enum { #if BB_BIG_ENDIAN COMPRESS_MAGIC = 0x1f9d, - GZIP_MAGIC = 0x1f8b, - BZIP2_MAGIC = ('B'<<8) + 'Z', - XZ_MAGIC1 = (0xfd<<8) + '7', - XZ_MAGIC2 = ((((('z'<<8) + 'X')<<8) + 'Z')<<8) + 0, + GZIP_MAGIC = 0x1f8b, + BZIP2_MAGIC = 'B' * 256 + 'Z', + XZ_MAGIC1 = 0xfd * 256 + '7', + XZ_MAGIC2 = (('z' * 256 + 'X') * 256 + 'Z') * 256 + 0, + /* Different form: 32 bits, then 16 bits: */ + XZ_MAGIC1a = ((0xfd * 256 + '7') * 256 + 'z') * 256 + 'X', + XZ_MAGIC2a = 'Z' * 256 + 0, #else COMPRESS_MAGIC = 0x9d1f, - GZIP_MAGIC = 0x8b1f, - BZIP2_MAGIC = ('Z'<<8) + 'B', - XZ_MAGIC1 = ('7'<<8) + 0xfd, - XZ_MAGIC2 = (((((0<<8) + 'Z')<<8) + 'X')<<8) + 'z', + GZIP_MAGIC = 0x8b1f, + BZIP2_MAGIC = 'Z' * 256 + 'B', + XZ_MAGIC1 = '7' * 256 + 0xfd, + XZ_MAGIC2 = ((0 * 256 + 'Z') * 256 + 'X') * 256 + 'z', + XZ_MAGIC1a = (('X' * 256 + 'z') * 256 + '7') * 256 + 0xfd, + XZ_MAGIC2a = 0 * 256 + 'Z', #endif }; @@ -196,7 +201,7 @@ typedef struct inflate_unzip_result { } inflate_unzip_result; IF_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC; -/* xz unpacker takes .xz stream from offset 0 */ +/* xz unpacker takes .xz stream from offset 6 */ IF_DESKTOP(long long) int unpack_xz_stream(int src_fd, int dst_fd) FAST_FUNC; /* lzma unpacker takes .lzma stream from offset 0 */ IF_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; diff --git a/libbb/read_printf.c b/libbb/read_printf.c index 3aee075c6..6780b94ef 100644 --- a/libbb/read_printf.c +++ b/libbb/read_printf.c @@ -296,8 +296,8 @@ void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) if (magic.b32[0] == XZ_MAGIC2) { # if BB_MMU xformer = unpack_xz_stream; - /* unpack_xz_stream wants fd at position 0 */ - xlseek(fd, offset, SEEK_CUR); + /* unpack_xz_stream wants fd at position 6, no need to seek */ + //xlseek(fd, offset, SEEK_CUR); # else xformer_prog = "unxz"; # endif