On Monday 28 January 2008 04:17, JoSH Lehan wrote:
> Thanks for responding.
>
> > Failing that, at least give a reproducible testcase -
> > how do you force short reads?
> > (no promices that I can work on it soon, though... sorry).
>
> To give unzip a short read, have it decompress data that comes in
> through a pipe.
>
> cat myfile.zip | unzip -
>
> This should quickly reproduce the problem. As a worst case scenario,
> let unzip only have one byte at a time.
>
> cat myfile.zip | dd bs=1 | unzip -
>
> The zipfile you're decompressing should have multiple files in it.
> Only the first file will work. The remaining files should fail with
> an error.
Please test attached fix.
--
vda
diff -d -urpN busybox.0/archival/libunarchive/decompress_unzip.c busybox.1/archival/libunarchive/decompress_unzip.c
--- busybox.0/archival/libunarchive/decompress_unzip.c 2008-02-04 11:38:33.000000000 +0000
+++ busybox.1/archival/libunarchive/decompress_unzip.c 2008-02-04 12:09:23.000000000 +0000
@@ -85,7 +85,8 @@ typedef struct state_t {
/* input (compressed) data */
unsigned char *bytebuffer; /* buffer itself */
- unsigned bytebuffer_max; /* buffer size */
+ off_t to_read; /* compressed bytes to read (unzip only, -1 for gunzip) */
+// unsigned bytebuffer_max; /* buffer size */
unsigned bytebuffer_offset; /* buffer position */
unsigned bytebuffer_size; /* how much data is there (size <= max) */
@@ -126,7 +127,10 @@ typedef struct state_t {
#define gunzip_crc_table (S()gunzip_crc_table )
#define gunzip_bb (S()gunzip_bb )
#define gunzip_bk (S()gunzip_bk )
-#define bytebuffer_max (S()bytebuffer_max )
+#define to_read (S()to_read )
+// #define bytebuffer_max (S()bytebuffer_max )
+// Both gunzip and unzip can use constant buffer size now (16k):
+#define bytebuffer_max 0x4000
#define bytebuffer (S()bytebuffer )
#define bytebuffer_offset (S()bytebuffer_offset )
#define bytebuffer_size (S()bytebuffer_size )
@@ -251,13 +255,18 @@ static unsigned fill_bitbuffer(STATE_PAR
{
while (*current < required) {
if (bytebuffer_offset >= bytebuffer_size) {
+ unsigned sz = bytebuffer_max - 4;
+ if (to_read >= 0 && to_read < sz) /* unzip only */
+ sz = to_read;
/* Leave the first 4 bytes empty so we can always unwind the bitbuffer
* to the front of the bytebuffer */
- bytebuffer_size = safe_read(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 4);
+ bytebuffer_size = safe_read(gunzip_src_fd, &bytebuffer[4], sz);
if ((int)bytebuffer_size < 1) {
error_msg = "unexpected end of file";
abort_unzip(PASS_STATE_ONLY);
}
+ if (to_read >= 0) /* unzip only */
+ to_read -= bytebuffer_size;
bytebuffer_size += 4;
bytebuffer_offset = 4;
}
@@ -1025,14 +1034,15 @@ inflate_unzip_internal(STATE_PARAM int i
/* For unzip */
USE_DESKTOP(long long) int
-inflate_unzip(inflate_unzip_result *res, unsigned bufsize, int in, int out)
+inflate_unzip(inflate_unzip_result *res, off_t compr_size, int in, int out)
{
USE_DESKTOP(long long) int n;
DECLARE_STATE;
ALLOC_STATE;
- bytebuffer_max = bufsize + 4;
+ to_read = compr_size;
+// bytebuffer_max = 0x8000;
bytebuffer_offset = 4;
bytebuffer = xmalloc(bytebuffer_max);
n = inflate_unzip_internal(PASS_STATE in, out);
@@ -1176,7 +1186,8 @@ unpack_gz_stream(int in, int out)
n = 0;
ALLOC_STATE;
- bytebuffer_max = 0x8000;
+ to_read = -1;
+// bytebuffer_max = 0x8000;
bytebuffer = xmalloc(bytebuffer_max);
gunzip_src_fd = in;
diff -d -urpN busybox.0/include/unarchive.h busybox.1/include/unarchive.h
--- busybox.0/include/unarchive.h 2008-02-04 11:38:39.000000000 +0000
+++ busybox.1/include/unarchive.h 2008-02-04 12:09:23.000000000 +0000
@@ -109,7 +109,7 @@ typedef struct inflate_unzip_result {
} inflate_unzip_result;
extern USE_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd);
-extern USE_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, unsigned bufsize, int src_fd, int dst_fd);
+extern USE_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd);
extern USE_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd);
extern USE_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd);
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox