xz compression detection: avoid the need to seek
No binary (build failed)
—
(log yok)
| @@ -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; | |
| @@ -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; | |
| @@ -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: | |
| @@ -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; | |
| @@ -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 | |