Stop tracking buffer size - it is a constant.
authorDenis Vlasenko <vda.linux@googlemail.com>
Fri, 5 Jan 2007 14:04:47 +0000 (14:04 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Fri, 5 Jan 2007 14:04:47 +0000 (14:04 -0000)
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!

archival/libunarchive/decompress_unlzma.c

index c1b0a31189466c82231d50e4a20f2d54e82560bc..15a0275b4732fc6739681c9c769c6e65c0028077 100644 (file)
 typedef struct {
        int fd;
        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;
-       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 range;
        uint32_t bound;
 } rc_t;
 
-//#define RC_BUFFER ((uint8_t*)(void*)(rc+1))
-#define RC_BUFFER ((uint8_t*)(rc+1))
-
 #define RC_TOP_BITS 24
 #define RC_MOVE_BITS 5
 #define RC_MODEL_TOTAL_BITS 11
@@ -41,24 +47,24 @@ typedef struct {
 /* Called twice: once at startup and once in rc_normalize() */
 static void rc_read(rc_t * rc)
 {
-       rc->buffer_size = read(rc->fd, RC_BUFFER, rc->buffer_size);
-       if (rc->buffer_size <= 0)
+       int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE);
+       if (buffer_size <= 0)
                bb_error_msg_and_die("unexpected EOF");
        rc->ptr = RC_BUFFER;
-       rc->buffer_end = RC_BUFFER + rc->buffer_size;
+       rc->buffer_end = RC_BUFFER + buffer_size;
 }
 
 /* Called once */
-static rc_t* rc_init(int fd, int buffer_size)
+static rc_t* rc_init(int fd) /*, int buffer_size) */
 {
        int i;
        rc_t* rc;
 
-       rc = xmalloc(sizeof(rc_t) + buffer_size);
+       rc = xmalloc(sizeof(rc_t) + RC_BUFFER_SIZE);
 
        rc->fd = fd;
-       rc->buffer_size = buffer_size;
-       rc->buffer_end = RC_BUFFER + rc->buffer_size;
+       /* rc->buffer_size = buffer_size; */
+       rc->buffer_end = RC_BUFFER + RC_BUFFER_SIZE;
        rc->ptr = rc->buffer_end;
 
        rc->code = 0;
@@ -168,7 +174,7 @@ typedef struct {
 } __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. */
 enum {
        LZMA_BASE_SIZE = 1846,
@@ -244,8 +250,7 @@ unlzma(int src_fd, int dst_fd)
        int state = 0;
        uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
 
-       if (read(src_fd, &header, sizeof(header)) != sizeof(header))
-               bb_error_msg_and_die("can't read header");
+       xread(src_fd, &header, sizeof(header));
 
        if (header.pos >= (9 * 5 * 5))
                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++)
                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) {
                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) {
                                buffer_pos = 0;
                                global_pos += header.dict_size;
-                               // FIXME: error check
-                               write(dst_fd, buffer, header.dict_size);
+                               if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size)
+                                       goto bad;
                                USE_DESKTOP(total_written += header.dict_size;)
                        }
                        if (state < 4)
@@ -358,8 +363,8 @@ unlzma(int src_fd, int dst_fd)
                                                if (buffer_pos == header.dict_size) {
                                                        buffer_pos = 0;
                                                        global_pos += header.dict_size;
-                                                       // FIXME: error check
-                                                       write(dst_fd, buffer, header.dict_size);
+                                                       if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size)
+                                                               goto bad;
                                                        USE_DESKTOP(total_written += header.dict_size;)
                                                }
                                                continue;
@@ -471,8 +476,8 @@ unlzma(int src_fd, int dst_fd)
                                if (buffer_pos == header.dict_size) {
                                        buffer_pos = 0;
                                        global_pos += header.dict_size;
-                                       // FIXME: error check
-                                       write(dst_fd, buffer, header.dict_size);
+                                       if (full_write(dst_fd, buffer, header.dict_size) != header.dict_size)
+                                               goto bad;
                                        USE_DESKTOP(total_written += header.dict_size;)
                                }
                                len--;
@@ -480,9 +485,13 @@ unlzma(int src_fd, int dst_fd)
                }
        }
 
-       // FIXME: error check
-       write(dst_fd, buffer, buffer_pos);
-       USE_DESKTOP(total_written += buffer_pos;)
+
+       if (full_write(dst_fd, buffer, buffer_pos) != buffer_pos) {
+ bad:
+               rc_free(rc);
+               return -1;
+       }
        rc_free(rc);
+       USE_DESKTOP(total_written += buffer_pos;)
        return USE_DESKTOP(total_written) + 0;
 }