aboutsummaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-27 15:48:45 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-27 15:48:45 +0000
commit2bbdda09dfaf5f2c788ce38aba80a1e562c954c8 (patch)
treebbb21e80c548f0366de676df9e216cabd2d86303 /archival
parentac2b50ebeaa23d75920fba71cf7a2683690c17da (diff)
downloadbusybox-w32-2bbdda09dfaf5f2c788ce38aba80a1e562c954c8.tar.gz
busybox-w32-2bbdda09dfaf5f2c788ce38aba80a1e562c954c8.tar.bz2
busybox-w32-2bbdda09dfaf5f2c788ce38aba80a1e562c954c8.zip
unlzma: fix memory leak (Pascal Bellard)
Diffstat (limited to 'archival')
-rw-r--r--archival/libunarchive/decompress_unlzma.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/archival/libunarchive/decompress_unlzma.c b/archival/libunarchive/decompress_unlzma.c
index 79df70179..2cfcd9b7d 100644
--- a/archival/libunarchive/decompress_unlzma.c
+++ b/archival/libunarchive/decompress_unlzma.c
@@ -45,7 +45,7 @@ typedef struct {
45 45
46 46
47/* Called twice: once at startup and once in rc_normalize() */ 47/* Called twice: once at startup and once in rc_normalize() */
48static void rc_read(rc_t * rc) 48static void rc_read(rc_t *rc)
49{ 49{
50 int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE); 50 int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE);
51 if (buffer_size <= 0) 51 if (buffer_size <= 0)
@@ -58,9 +58,9 @@ static void rc_read(rc_t * rc)
58static rc_t* rc_init(int fd) /*, int buffer_size) */ 58static rc_t* rc_init(int fd) /*, int buffer_size) */
59{ 59{
60 int i; 60 int i;
61 rc_t* rc; 61 rc_t *rc;
62 62
63 rc = xmalloc(sizeof(rc_t) + RC_BUFFER_SIZE); 63 rc = xmalloc(sizeof(*rc) + RC_BUFFER_SIZE);
64 64
65 rc->fd = fd; 65 rc->fd = fd;
66 /* rc->buffer_size = buffer_size; */ 66 /* rc->buffer_size = buffer_size; */
@@ -78,21 +78,20 @@ static rc_t* rc_init(int fd) /*, int buffer_size) */
78} 78}
79 79
80/* Called once */ 80/* Called once */
81static ALWAYS_INLINE void rc_free(rc_t * rc) 81static ALWAYS_INLINE void rc_free(rc_t *rc)
82{ 82{
83 if (ENABLE_FEATURE_CLEAN_UP) 83 free(rc);
84 free(rc);
85} 84}
86 85
87/* Called twice, but one callsite is in speed_inline'd rc_is_bit_0_helper() */ 86/* Called twice, but one callsite is in speed_inline'd rc_is_bit_0_helper() */
88static void rc_do_normalize(rc_t * rc) 87static void rc_do_normalize(rc_t *rc)
89{ 88{
90 if (rc->ptr >= rc->buffer_end) 89 if (rc->ptr >= rc->buffer_end)
91 rc_read(rc); 90 rc_read(rc);
92 rc->range <<= 8; 91 rc->range <<= 8;
93 rc->code = (rc->code << 8) | *rc->ptr++; 92 rc->code = (rc->code << 8) | *rc->ptr++;
94} 93}
95static ALWAYS_INLINE void rc_normalize(rc_t * rc) 94static ALWAYS_INLINE void rc_normalize(rc_t *rc)
96{ 95{
97 if (rc->range < (1 << RC_TOP_BITS)) { 96 if (rc->range < (1 << RC_TOP_BITS)) {
98 rc_do_normalize(rc); 97 rc_do_normalize(rc);
@@ -105,25 +104,25 @@ static ALWAYS_INLINE void rc_normalize(rc_t * rc)
105 * Thus rc_is_bit_0 is always inlined, and rc_is_bit_0_helper is inlined 104 * Thus rc_is_bit_0 is always inlined, and rc_is_bit_0_helper is inlined
106 * only if we compile for speed. 105 * only if we compile for speed.
107 */ 106 */
108static speed_inline uint32_t rc_is_bit_0_helper(rc_t * rc, uint16_t * p) 107static speed_inline uint32_t rc_is_bit_0_helper(rc_t *rc, uint16_t *p)
109{ 108{
110 rc_normalize(rc); 109 rc_normalize(rc);
111 rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS); 110 rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
112 return rc->bound; 111 return rc->bound;
113} 112}
114static ALWAYS_INLINE int rc_is_bit_0(rc_t * rc, uint16_t * p) 113static ALWAYS_INLINE int rc_is_bit_0(rc_t *rc, uint16_t *p)
115{ 114{
116 uint32_t t = rc_is_bit_0_helper(rc, p); 115 uint32_t t = rc_is_bit_0_helper(rc, p);
117 return rc->code < t; 116 return rc->code < t;
118} 117}
119 118
120/* Called ~10 times, but very small, thus inlined */ 119/* Called ~10 times, but very small, thus inlined */
121static speed_inline void rc_update_bit_0(rc_t * rc, uint16_t * p) 120static speed_inline void rc_update_bit_0(rc_t *rc, uint16_t *p)
122{ 121{
123 rc->range = rc->bound; 122 rc->range = rc->bound;
124 *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS; 123 *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS;
125} 124}
126static speed_inline void rc_update_bit_1(rc_t * rc, uint16_t * p) 125static speed_inline void rc_update_bit_1(rc_t *rc, uint16_t *p)
127{ 126{
128 rc->range -= rc->bound; 127 rc->range -= rc->bound;
129 rc->code -= rc->bound; 128 rc->code -= rc->bound;
@@ -131,7 +130,7 @@ static speed_inline void rc_update_bit_1(rc_t * rc, uint16_t * p)
131} 130}
132 131
133/* Called 4 times in unlzma loop */ 132/* Called 4 times in unlzma loop */
134static int rc_get_bit(rc_t * rc, uint16_t * p, int *symbol) 133static int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol)
135{ 134{
136 if (rc_is_bit_0(rc, p)) { 135 if (rc_is_bit_0(rc, p)) {
137 rc_update_bit_0(rc, p); 136 rc_update_bit_0(rc, p);
@@ -145,7 +144,7 @@ static int rc_get_bit(rc_t * rc, uint16_t * p, int *symbol)
145} 144}
146 145
147/* Called once */ 146/* Called once */
148static ALWAYS_INLINE int rc_direct_bit(rc_t * rc) 147static ALWAYS_INLINE int rc_direct_bit(rc_t *rc)
149{ 148{
150 rc_normalize(rc); 149 rc_normalize(rc);
151 rc->range >>= 1; 150 rc->range >>= 1;
@@ -158,7 +157,7 @@ static ALWAYS_INLINE int rc_direct_bit(rc_t * rc)
158 157
159/* Called twice */ 158/* Called twice */
160static speed_inline void 159static speed_inline void
161rc_bit_tree_decode(rc_t * rc, uint16_t * p, int num_levels, int *symbol) 160rc_bit_tree_decode(rc_t *rc, uint16_t *p, int num_levels, int *symbol)
162{ 161{
163 int i = num_levels; 162 int i = num_levels;
164 163
@@ -489,12 +488,16 @@ unpack_lzma_stream(int src_fd, int dst_fd)
489 } 488 }
490 } 489 }
491 490
492 if (full_write(dst_fd, buffer, buffer_pos) != (ssize_t)buffer_pos) { 491 {
492 SKIP_DESKTOP(int total_written = 0; /* success */)
493 USE_DESKTOP(total_written += buffer_pos;)
494 if (full_write(dst_fd, buffer, buffer_pos) != (ssize_t)buffer_pos) {
493 bad: 495 bad:
496 total_written = -1; /* failure */
497 }
494 rc_free(rc); 498 rc_free(rc);
495 return -1; 499 free(p);
500 free(buffer);
501 return total_written;
496 } 502 }
497 rc_free(rc);
498 USE_DESKTOP(total_written += buffer_pos;)
499 return USE_DESKTOP(total_written) + 0;
500} 503}