xz compression detection: avoid the need to seek
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 1 Jul 2010 03:12:28 +0000 (05:12 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 1 Jul 2010 03:12:28 +0000 (05:12 +0200)
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 <vda.linux@googlemail.com>
archival/bbunzip.c
archival/libunarchive/decompress_unxz.c
archival/rpm2cpio.c
include/unarchive.h
libbb/read_printf.c

index b243afb2ee56cea01afae6e445db7fc173cd5ddb..832a7bbf3129194236d1787d3cf262567d87c9d3 100644 (file)
@@ -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;
index 5d7513a2eb1064b4dd1afdad76e9d087c058e3ae..721acd907f0a4e214951e11c5862df3cb026e11d 100644 (file)
@@ -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;
 
index 1f67fa8870548614f07382e6beccae0a53dbe285..b23d5afa9669ba71c87560537e4b2b09fea2bbc8 100644 (file)
@@ -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:
index b4cf16082350057c0445c647c901e6d09f2be38f..3b8e1575aa669e06f53a73cd26d372326c8fa78f 100644 (file)
@@ -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;
index 3aee075c6afd11680e0194ed512679ba2b9fc99b..6780b94efc472b2970695c48808fa116faaa2f7e 100644 (file)
@@ -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