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!
This commit is contained in:
parent
98b8e9487d
commit
3376298b59
@ -22,17 +22,23 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
int fd;
|
int fd;
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
// uint8_t *buffer;
|
|
||||||
|
/* Was keeping rc on stack in unlzma and separately allocating buffer,
|
||||||
|
* but with "buffer 'attached to' allocated rc" code is smaller: */
|
||||||
|
/* uint8_t *buffer; */
|
||||||
|
#define RC_BUFFER ((uint8_t*)(rc+1))
|
||||||
|
|
||||||
uint8_t *buffer_end;
|
uint8_t *buffer_end;
|
||||||
int buffer_size;
|
|
||||||
|
/* Had provisions for variable buffer, but we don't need it here */
|
||||||
|
/* int buffer_size; */
|
||||||
|
#define RC_BUFFER_SIZE 0x10000
|
||||||
|
|
||||||
uint32_t code;
|
uint32_t code;
|
||||||
uint32_t range;
|
uint32_t range;
|
||||||
uint32_t bound;
|
uint32_t bound;
|
||||||
} rc_t;
|
} rc_t;
|
||||||
|
|
||||||
//#define RC_BUFFER ((uint8_t*)(void*)(rc+1))
|
|
||||||
#define RC_BUFFER ((uint8_t*)(rc+1))
|
|
||||||
|
|
||||||
#define RC_TOP_BITS 24
|
#define RC_TOP_BITS 24
|
||||||
#define RC_MOVE_BITS 5
|
#define RC_MOVE_BITS 5
|
||||||
#define RC_MODEL_TOTAL_BITS 11
|
#define RC_MODEL_TOTAL_BITS 11
|
||||||
@ -41,24 +47,24 @@ typedef struct {
|
|||||||
/* Called twice: once at startup and once in rc_normalize() */
|
/* Called twice: once at startup and once in rc_normalize() */
|
||||||
static void rc_read(rc_t * rc)
|
static void rc_read(rc_t * rc)
|
||||||
{
|
{
|
||||||
rc->buffer_size = read(rc->fd, RC_BUFFER, rc->buffer_size);
|
int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE);
|
||||||
if (rc->buffer_size <= 0)
|
if (buffer_size <= 0)
|
||||||
bb_error_msg_and_die("unexpected EOF");
|
bb_error_msg_and_die("unexpected EOF");
|
||||||
rc->ptr = RC_BUFFER;
|
rc->ptr = RC_BUFFER;
|
||||||
rc->buffer_end = RC_BUFFER + rc->buffer_size;
|
rc->buffer_end = RC_BUFFER + buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called once */
|
/* Called once */
|
||||||
static rc_t* rc_init(int fd, int buffer_size)
|
static rc_t* rc_init(int fd) /*, int buffer_size) */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
rc_t* rc;
|
rc_t* rc;
|
||||||
|
|
||||||
rc = xmalloc(sizeof(rc_t) + buffer_size);
|
rc = xmalloc(sizeof(rc_t) + RC_BUFFER_SIZE);
|
||||||
|
|
||||||
rc->fd = fd;
|
rc->fd = fd;
|
||||||
rc->buffer_size = buffer_size;
|
/* rc->buffer_size = buffer_size; */
|
||||||
rc->buffer_end = RC_BUFFER + rc->buffer_size;
|
rc->buffer_end = RC_BUFFER + RC_BUFFER_SIZE;
|
||||||
rc->ptr = rc->buffer_end;
|
rc->ptr = rc->buffer_end;
|
||||||
|
|
||||||
rc->code = 0;
|
rc->code = 0;
|
||||||
@ -168,7 +174,7 @@ typedef struct {
|
|||||||
} __attribute__ ((packed)) lzma_header_t;
|
} __attribute__ ((packed)) lzma_header_t;
|
||||||
|
|
||||||
|
|
||||||
/* #defines will make compiler to compute/optimize each one with each usage.
|
/* #defines will force compiler to compute/optimize each one with each usage.
|
||||||
* Have heart and use enum instead. */
|
* Have heart and use enum instead. */
|
||||||
enum {
|
enum {
|
||||||
LZMA_BASE_SIZE = 1846,
|
LZMA_BASE_SIZE = 1846,
|
||||||
@ -244,8 +250,7 @@ unlzma(int src_fd, int dst_fd)
|
|||||||
int state = 0;
|
int state = 0;
|
||||||
uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
|
uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
|
||||||
|
|
||||||
if (read(src_fd, &header, sizeof(header)) != sizeof(header))
|
xread(src_fd, &header, sizeof(header));
|
||||||
bb_error_msg_and_die("can't read header");
|
|
||||||
|
|
||||||
if (header.pos >= (9 * 5 * 5))
|
if (header.pos >= (9 * 5 * 5))
|
||||||
bb_error_msg_and_die("bad header");
|
bb_error_msg_and_die("bad header");
|
||||||
@ -270,7 +275,7 @@ unlzma(int src_fd, int dst_fd)
|
|||||||
for (i = 0; i < num_probs; i++)
|
for (i = 0; i < num_probs; i++)
|
||||||
p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
|
p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
|
||||||
|
|
||||||
rc = rc_init(src_fd, 0x10000);
|
rc = rc_init(src_fd); /*, RC_BUFFER_SIZE); */
|
||||||
|
|
||||||
while (global_pos + buffer_pos < header.dst_size) {
|
while (global_pos + buffer_pos < header.dst_size) {
|
||||||
int pos_state = (buffer_pos + global_pos) & pos_state_mask;
|
int pos_state = (buffer_pos + global_pos) & pos_state_mask;
|
||||||
@ -316,8 +321,8 @@ unlzma(int src_fd, int dst_fd)
|
|||||||
if (buffer_pos == header.dict_size) {
|
if (buffer_pos == header.dict_size) {
|
||||||
buffer_pos = 0;
|
buffer_pos = 0;
|
||||||
global_pos += header.dict_size;
|
global_pos += header.dict_size;
|
||||||
// FIXME: error check
|
if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size)
|
||||||
write(dst_fd, buffer, header.dict_size);
|
goto bad;
|
||||||
USE_DESKTOP(total_written += header.dict_size;)
|
USE_DESKTOP(total_written += header.dict_size;)
|
||||||
}
|
}
|
||||||
if (state < 4)
|
if (state < 4)
|
||||||
@ -358,8 +363,8 @@ unlzma(int src_fd, int dst_fd)
|
|||||||
if (buffer_pos == header.dict_size) {
|
if (buffer_pos == header.dict_size) {
|
||||||
buffer_pos = 0;
|
buffer_pos = 0;
|
||||||
global_pos += header.dict_size;
|
global_pos += header.dict_size;
|
||||||
// FIXME: error check
|
if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size)
|
||||||
write(dst_fd, buffer, header.dict_size);
|
goto bad;
|
||||||
USE_DESKTOP(total_written += header.dict_size;)
|
USE_DESKTOP(total_written += header.dict_size;)
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -471,8 +476,8 @@ unlzma(int src_fd, int dst_fd)
|
|||||||
if (buffer_pos == header.dict_size) {
|
if (buffer_pos == header.dict_size) {
|
||||||
buffer_pos = 0;
|
buffer_pos = 0;
|
||||||
global_pos += header.dict_size;
|
global_pos += header.dict_size;
|
||||||
// FIXME: error check
|
if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size)
|
||||||
write(dst_fd, buffer, header.dict_size);
|
goto bad;
|
||||||
USE_DESKTOP(total_written += header.dict_size;)
|
USE_DESKTOP(total_written += header.dict_size;)
|
||||||
}
|
}
|
||||||
len--;
|
len--;
|
||||||
@ -480,9 +485,13 @@ unlzma(int src_fd, int dst_fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: error check
|
|
||||||
write(dst_fd, buffer, buffer_pos);
|
if (full_write(dst_fd, buffer, buffer_pos) != buffer_pos) {
|
||||||
USE_DESKTOP(total_written += buffer_pos;)
|
bad:
|
||||||
|
rc_free(rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
rc_free(rc);
|
rc_free(rc);
|
||||||
|
USE_DESKTOP(total_written += buffer_pos;)
|
||||||
return USE_DESKTOP(total_written) + 0;
|
return USE_DESKTOP(total_written) + 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user