diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-05 14:04:47 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-05 14:04:47 +0000 |
| commit | 3376298b59abea4ec3c69fe1dbe5898db260cc5a (patch) | |
| tree | a831c13cfb8e839ddf5d020a879d3e4d8c0376f8 | |
| parent | 98b8e9487dc40100d8031136f2241a66ce9dffb0 (diff) | |
| download | busybox-w32-3376298b59abea4ec3c69fe1dbe5898db260cc5a.tar.gz busybox-w32-3376298b59abea4ec3c69fe1dbe5898db260cc5a.tar.bz2 busybox-w32-3376298b59abea4ec3c69fe1dbe5898db260cc5a.zip | |
Stop tracking buffer size - it is a constant.
Stop ignoring write errors.
Fix bugs in this line:
rc->buffer_size = read(rc->fd, RC_BUFFER, rc->buffer_size);
(a) should use safe_read()
(b) just ONE short read (e.g. 4 bytes) will make ALL future reads short!
| -rw-r--r-- | archival/libunarchive/decompress_unlzma.c | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/archival/libunarchive/decompress_unlzma.c b/archival/libunarchive/decompress_unlzma.c index c1b0a3118..15a0275b4 100644 --- a/archival/libunarchive/decompress_unlzma.c +++ b/archival/libunarchive/decompress_unlzma.c | |||
| @@ -22,17 +22,23 @@ | |||
| 22 | typedef struct { | 22 | typedef struct { |
| 23 | int fd; | 23 | int fd; |
| 24 | uint8_t *ptr; | 24 | uint8_t *ptr; |
| 25 | // uint8_t *buffer; | 25 | |
| 26 | /* Was keeping rc on stack in unlzma and separately allocating buffer, | ||
| 27 | * but with "buffer 'attached to' allocated rc" code is smaller: */ | ||
| 28 | /* uint8_t *buffer; */ | ||
| 29 | #define RC_BUFFER ((uint8_t*)(rc+1)) | ||
| 30 | |||
| 26 | uint8_t *buffer_end; | 31 | uint8_t *buffer_end; |
| 27 | int buffer_size; | 32 | |
| 33 | /* Had provisions for variable buffer, but we don't need it here */ | ||
| 34 | /* int buffer_size; */ | ||
| 35 | #define RC_BUFFER_SIZE 0x10000 | ||
| 36 | |||
| 28 | uint32_t code; | 37 | uint32_t code; |
| 29 | uint32_t range; | 38 | uint32_t range; |
| 30 | uint32_t bound; | 39 | uint32_t bound; |
| 31 | } rc_t; | 40 | } rc_t; |
| 32 | 41 | ||
| 33 | //#define RC_BUFFER ((uint8_t*)(void*)(rc+1)) | ||
| 34 | #define RC_BUFFER ((uint8_t*)(rc+1)) | ||
| 35 | |||
| 36 | #define RC_TOP_BITS 24 | 42 | #define RC_TOP_BITS 24 |
| 37 | #define RC_MOVE_BITS 5 | 43 | #define RC_MOVE_BITS 5 |
| 38 | #define RC_MODEL_TOTAL_BITS 11 | 44 | #define RC_MODEL_TOTAL_BITS 11 |
| @@ -41,24 +47,24 @@ typedef struct { | |||
| 41 | /* Called twice: once at startup and once in rc_normalize() */ | 47 | /* Called twice: once at startup and once in rc_normalize() */ |
| 42 | static void rc_read(rc_t * rc) | 48 | static void rc_read(rc_t * rc) |
| 43 | { | 49 | { |
| 44 | rc->buffer_size = read(rc->fd, RC_BUFFER, rc->buffer_size); | 50 | int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE); |
| 45 | if (rc->buffer_size <= 0) | 51 | if (buffer_size <= 0) |
| 46 | bb_error_msg_and_die("unexpected EOF"); | 52 | bb_error_msg_and_die("unexpected EOF"); |
| 47 | rc->ptr = RC_BUFFER; | 53 | rc->ptr = RC_BUFFER; |
| 48 | rc->buffer_end = RC_BUFFER + rc->buffer_size; | 54 | rc->buffer_end = RC_BUFFER + buffer_size; |
| 49 | } | 55 | } |
| 50 | 56 | ||
| 51 | /* Called once */ | 57 | /* Called once */ |
| 52 | static rc_t* rc_init(int fd, int buffer_size) | 58 | static rc_t* rc_init(int fd) /*, int buffer_size) */ |
| 53 | { | 59 | { |
| 54 | int i; | 60 | int i; |
| 55 | rc_t* rc; | 61 | rc_t* rc; |
| 56 | 62 | ||
| 57 | rc = xmalloc(sizeof(rc_t) + buffer_size); | 63 | rc = xmalloc(sizeof(rc_t) + RC_BUFFER_SIZE); |
| 58 | 64 | ||
| 59 | rc->fd = fd; | 65 | rc->fd = fd; |
| 60 | rc->buffer_size = buffer_size; | 66 | /* rc->buffer_size = buffer_size; */ |
| 61 | rc->buffer_end = RC_BUFFER + rc->buffer_size; | 67 | rc->buffer_end = RC_BUFFER + RC_BUFFER_SIZE; |
| 62 | rc->ptr = rc->buffer_end; | 68 | rc->ptr = rc->buffer_end; |
| 63 | 69 | ||
| 64 | rc->code = 0; | 70 | rc->code = 0; |
| @@ -168,7 +174,7 @@ typedef struct { | |||
| 168 | } __attribute__ ((packed)) lzma_header_t; | 174 | } __attribute__ ((packed)) lzma_header_t; |
| 169 | 175 | ||
| 170 | 176 | ||
| 171 | /* #defines will make compiler to compute/optimize each one with each usage. | 177 | /* #defines will force compiler to compute/optimize each one with each usage. |
| 172 | * Have heart and use enum instead. */ | 178 | * Have heart and use enum instead. */ |
| 173 | enum { | 179 | enum { |
| 174 | LZMA_BASE_SIZE = 1846, | 180 | LZMA_BASE_SIZE = 1846, |
| @@ -244,8 +250,7 @@ unlzma(int src_fd, int dst_fd) | |||
| 244 | int state = 0; | 250 | int state = 0; |
| 245 | uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; | 251 | uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; |
| 246 | 252 | ||
| 247 | if (read(src_fd, &header, sizeof(header)) != sizeof(header)) | 253 | xread(src_fd, &header, sizeof(header)); |
| 248 | bb_error_msg_and_die("can't read header"); | ||
| 249 | 254 | ||
| 250 | if (header.pos >= (9 * 5 * 5)) | 255 | if (header.pos >= (9 * 5 * 5)) |
| 251 | bb_error_msg_and_die("bad header"); | 256 | bb_error_msg_and_die("bad header"); |
| @@ -270,7 +275,7 @@ unlzma(int src_fd, int dst_fd) | |||
| 270 | for (i = 0; i < num_probs; i++) | 275 | for (i = 0; i < num_probs; i++) |
| 271 | p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; | 276 | p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; |
| 272 | 277 | ||
| 273 | rc = rc_init(src_fd, 0x10000); | 278 | rc = rc_init(src_fd); /*, RC_BUFFER_SIZE); */ |
| 274 | 279 | ||
| 275 | while (global_pos + buffer_pos < header.dst_size) { | 280 | while (global_pos + buffer_pos < header.dst_size) { |
| 276 | int pos_state = (buffer_pos + global_pos) & pos_state_mask; | 281 | int pos_state = (buffer_pos + global_pos) & pos_state_mask; |
| @@ -316,8 +321,8 @@ unlzma(int src_fd, int dst_fd) | |||
| 316 | if (buffer_pos == header.dict_size) { | 321 | if (buffer_pos == header.dict_size) { |
| 317 | buffer_pos = 0; | 322 | buffer_pos = 0; |
| 318 | global_pos += header.dict_size; | 323 | global_pos += header.dict_size; |
| 319 | // FIXME: error check | 324 | if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size) |
| 320 | write(dst_fd, buffer, header.dict_size); | 325 | goto bad; |
| 321 | USE_DESKTOP(total_written += header.dict_size;) | 326 | USE_DESKTOP(total_written += header.dict_size;) |
| 322 | } | 327 | } |
| 323 | if (state < 4) | 328 | if (state < 4) |
| @@ -358,8 +363,8 @@ unlzma(int src_fd, int dst_fd) | |||
| 358 | if (buffer_pos == header.dict_size) { | 363 | if (buffer_pos == header.dict_size) { |
| 359 | buffer_pos = 0; | 364 | buffer_pos = 0; |
| 360 | global_pos += header.dict_size; | 365 | global_pos += header.dict_size; |
| 361 | // FIXME: error check | 366 | if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size) |
| 362 | write(dst_fd, buffer, header.dict_size); | 367 | goto bad; |
| 363 | USE_DESKTOP(total_written += header.dict_size;) | 368 | USE_DESKTOP(total_written += header.dict_size;) |
| 364 | } | 369 | } |
| 365 | continue; | 370 | continue; |
| @@ -471,8 +476,8 @@ unlzma(int src_fd, int dst_fd) | |||
| 471 | if (buffer_pos == header.dict_size) { | 476 | if (buffer_pos == header.dict_size) { |
| 472 | buffer_pos = 0; | 477 | buffer_pos = 0; |
| 473 | global_pos += header.dict_size; | 478 | global_pos += header.dict_size; |
| 474 | // FIXME: error check | 479 | if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size) |
| 475 | write(dst_fd, buffer, header.dict_size); | 480 | goto bad; |
| 476 | USE_DESKTOP(total_written += header.dict_size;) | 481 | USE_DESKTOP(total_written += header.dict_size;) |
| 477 | } | 482 | } |
| 478 | len--; | 483 | len--; |
| @@ -480,9 +485,13 @@ unlzma(int src_fd, int dst_fd) | |||
| 480 | } | 485 | } |
| 481 | } | 486 | } |
| 482 | 487 | ||
| 483 | // FIXME: error check | 488 | |
| 484 | write(dst_fd, buffer, buffer_pos); | 489 | if (full_write(dst_fd, buffer, buffer_pos) != buffer_pos) { |
| 485 | USE_DESKTOP(total_written += buffer_pos;) | 490 | bad: |
| 491 | rc_free(rc); | ||
| 492 | return -1; | ||
| 493 | } | ||
| 486 | rc_free(rc); | 494 | rc_free(rc); |
| 495 | USE_DESKTOP(total_written += buffer_pos;) | ||
| 487 | return USE_DESKTOP(total_written) + 0; | 496 | return USE_DESKTOP(total_written) + 0; |
| 488 | } | 497 | } |
