Rizin
unix-like reverse engineering framework and cli tools
zip_algorithm_bzip2.c
Go to the documentation of this file.
1 /*
2  zip_algorithm_bzip2.c -- bzip2 (de)compression routines
3  Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner
4 
5  This file is part of libzip, a library to manipulate ZIP archives.
6  The authors can be contacted at <info@libzip.org>
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions
10  are met:
11  1. Redistributions of source code must retain the above copyright
12  notice, this list of conditions and the following disclaimer.
13  2. Redistributions in binary form must reproduce the above copyright
14  notice, this list of conditions and the following disclaimer in
15  the documentation and/or other materials provided with the
16  distribution.
17  3. The names of the authors may not be used to endorse or promote
18  products derived from this software without specific prior
19  written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
22  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 #include "zipint.h"
35 
36 #include <bzlib.h>
37 #include <limits.h>
38 #include <stdlib.h>
39 
40 struct ctx {
42  bool compress;
45  bz_stream zstr;
46 };
47 
48 
49 static zip_uint64_t
52 
54  return ZIP_UINT64_MAX;
55  }
56  return compressed_size;
57 }
58 
59 
60 static void *
61 allocate(bool compress, int compression_flags, zip_error_t *error) {
62  struct ctx *ctx;
63 
64  if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
65  return NULL;
66  }
67 
68  ctx->error = error;
71  if (ctx->compression_flags < 1 || ctx->compression_flags > 9) {
73  }
74  ctx->end_of_input = false;
75 
76  ctx->zstr.bzalloc = NULL;
77  ctx->zstr.bzfree = NULL;
78  ctx->zstr.opaque = NULL;
79 
80  return ctx;
81 }
82 
83 
84 static void *
86  return allocate(true, compression_flags, error);
87 }
88 
89 
90 static void *
92  return allocate(false, compression_flags, error);
93 }
94 
95 
96 static void
97 deallocate(void *ud) {
98  struct ctx *ctx = (struct ctx *)ud;
99 
100  free(ctx);
101 }
102 
103 
104 static zip_uint16_t
106  return 0;
107 }
108 
109 
110 static int
111 map_error(int ret) {
112  switch (ret) {
113  case BZ_FINISH_OK:
114  case BZ_FLUSH_OK:
115  case BZ_OK:
116  case BZ_RUN_OK:
117  case BZ_STREAM_END:
118  return ZIP_ER_OK;
119 
120  case BZ_DATA_ERROR:
121  case BZ_DATA_ERROR_MAGIC:
122  case BZ_UNEXPECTED_EOF:
123  return ZIP_ER_COMPRESSED_DATA;
124 
125  case BZ_MEM_ERROR:
126  return ZIP_ER_MEMORY;
127 
128  case BZ_PARAM_ERROR:
129  return ZIP_ER_INVAL;
130 
131  case BZ_CONFIG_ERROR: /* actually, bzip2 miscompiled */
132  case BZ_IO_ERROR:
133  case BZ_OUTBUFF_FULL:
134  case BZ_SEQUENCE_ERROR:
135  return ZIP_ER_INTERNAL;
136 
137  default:
138  return ZIP_ER_INTERNAL;
139  }
140 }
141 
142 static bool
143 start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) {
144  struct ctx *ctx = (struct ctx *)ud;
145  int ret;
146 
147  ctx->zstr.avail_in = 0;
148  ctx->zstr.next_in = NULL;
149  ctx->zstr.avail_out = 0;
150  ctx->zstr.next_out = NULL;
151 
152  if (ctx->compress) {
153  ret = BZ2_bzCompressInit(&ctx->zstr, ctx->compression_flags, 0, 30);
154  }
155  else {
156  ret = BZ2_bzDecompressInit(&ctx->zstr, 0, 0);
157  }
158 
159  if (ret != BZ_OK) {
160  zip_error_set(ctx->error, map_error(ret), 0);
161  return false;
162  }
163 
164  return true;
165 }
166 
167 
168 static bool
169 end(void *ud) {
170  struct ctx *ctx = (struct ctx *)ud;
171  int err;
172 
173  if (ctx->compress) {
174  err = BZ2_bzCompressEnd(&ctx->zstr);
175  }
176  else {
177  err = BZ2_bzDecompressEnd(&ctx->zstr);
178  }
179 
180  if (err != BZ_OK) {
182  return false;
183  }
184 
185  return true;
186 }
187 
188 
189 static bool
191  struct ctx *ctx = (struct ctx *)ud;
192 
193  if (length > UINT_MAX || ctx->zstr.avail_in > 0) {
195  return false;
196  }
197 
198  ctx->zstr.avail_in = (unsigned int)length;
199  ctx->zstr.next_in = (char *)data;
200 
201  return true;
202 }
203 
204 
205 static void
206 end_of_input(void *ud) {
207  struct ctx *ctx = (struct ctx *)ud;
208 
209  ctx->end_of_input = true;
210 }
211 
212 
215  struct ctx *ctx = (struct ctx *)ud;
216 
217  int ret;
218 
219  if (ctx->zstr.avail_in == 0 && !ctx->end_of_input) {
220  *length = 0;
222  }
223 
224  ctx->zstr.avail_out = (unsigned int)ZIP_MIN(UINT_MAX, *length);
225  ctx->zstr.next_out = (char *)data;
226 
227  if (ctx->compress) {
228  ret = BZ2_bzCompress(&ctx->zstr, ctx->end_of_input ? BZ_FINISH : BZ_RUN);
229  }
230  else {
231  ret = BZ2_bzDecompress(&ctx->zstr);
232  }
233 
234  *length = *length - ctx->zstr.avail_out;
235 
236  switch (ret) {
237  case BZ_FINISH_OK: /* compression */
238  return ZIP_COMPRESSION_OK;
239 
240  case BZ_OK: /* decompression */
241  case BZ_RUN_OK: /* compression */
242  if (ctx->zstr.avail_in == 0) {
244  }
245  return ZIP_COMPRESSION_OK;
246 
247  case BZ_STREAM_END:
248  return ZIP_COMPRESSION_END;
249 
250  default:
251  zip_error_set(ctx->error, map_error(ret), 0);
252  return ZIP_COMPRESSION_ERROR;
253  }
254 }
255 
256 /* clang-format off */
257 
261  deallocate,
263  46,
264  start,
265  end,
266  input,
267  end_of_input,
268  process
269 };
270 
271 
275  deallocate,
277  46,
278  start,
279  end,
280  input,
281  end_of_input,
282  process
283 };
284 
285 /* clang-format on */
static bool err
Definition: armass.c:435
int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
Definition: compress.c:68
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define ZIP_ER_INTERNAL
Definition: zip.h:125
ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int)
Definition: zip_error.c:126
#define ZIP_ER_COMPRESSED_DATA
Definition: zip.h:136
#define ZIP_ER_MEMORY
Definition: zip.h:119
#define ZIP_ER_OK
Definition: zip.h:105
#define ZIP_ER_INVAL
Definition: zip.h:123
void * malloc(size_t size)
Definition: malloc.c:123
static int
Definition: sfsocketcall.h:114
zip_uint16_t method
bool end_of_input
bz_stream zstr
int compression_flags
bool compress
zip_error_t * error
Definition: zip.h:284
Definition: zip.h:300
#define UINT_MAX
Definition: md5.h:55
uint64_t compressed_size
Definition: list.c:105
uint64_t uncompressed_size
Definition: list.c:106
void error(const char *msg)
Definition: untgz.c:593
static zip_uint64_t maximum_compressed_size(zip_uint64_t uncompressed_size)
static void deallocate(void *ud)
zip_compression_algorithm_t zip_algorithm_bzip2_decompress
zip_compression_algorithm_t zip_algorithm_bzip2_compress
static void * decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error)
static void * allocate(bool compress, int compression_flags, zip_error_t *error)
static void * compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error)
static bool start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes)
static bool end(void *ud)
static zip_uint16_t general_purpose_bit_flags(void *ud)
static int map_error(int ret)
static void end_of_input(void *ud)
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
static zip_compression_status_t process(void *ud, zip_uint8_t *data, zip_uint64_t *length)
uint64_t zip_uint64_t
Definition: zipconf.h:39
uint8_t zip_uint8_t
Definition: zipconf.h:33
uint16_t zip_uint16_t
Definition: zipconf.h:35
#define ZIP_UINT64_MAX
Definition: zipconf.h:55
enum zip_compression_status zip_compression_status_t
Definition: zipint.h:122
#define ZIP_MIN(a, b)
Definition: zipint.h:473
@ ZIP_COMPRESSION_NEED_DATA
Definition: zipint.h:119
@ ZIP_COMPRESSION_ERROR
Definition: zipint.h:118
@ ZIP_COMPRESSION_END
Definition: zipint.h:117
@ ZIP_COMPRESSION_OK
Definition: zipint.h:116