1 /*- 2 * Copyright (c) 2003-2007 Tim Kientzle 3 * Copyright (c) 2012 Michihiro NAKAJIMA 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "archive_platform.h" 28 29 __FBSDID("$FreeBSD$"); 30 31 #ifdef HAVE_UNISTD_H 32 #include <unistd.h> 33 #endif 34 #ifdef HAVE_ERRNO_H 35 #include <errno.h> 36 #endif 37 #ifdef HAVE_STDLIB_H 38 #include <stdlib.h> 39 #endif 40 #ifdef HAVE_STRING_H 41 #include <string.h> 42 #endif 43 #ifdef HAVE_UNISTD_H 44 #include <unistd.h> 45 #endif 46 #ifdef HAVE_LZO_LZOCONF_H 47 #include <lzo/lzoconf.h> 48 #endif 49 #ifdef HAVE_LZO_LZO1X_H 50 #include <lzo/lzo1x.h> 51 #endif 52 #ifdef HAVE_ZLIB_H 53 #include <zlib.h> /* for crc32 and adler32 */ 54 #endif 55 56 #include "archive.h" 57 #if !defined(HAVE_ZLIB_H) &&\ 58 defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) 59 #include "archive_crc32.h" 60 #endif 61 #include "archive_endian.h" 62 #include "archive_private.h" 63 #include "archive_read_private.h" 64 65 #ifndef HAVE_ZLIB_H 66 #define adler32 lzo_adler32 67 #endif 68 69 #define LZOP_HEADER_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a" 70 #define LZOP_HEADER_MAGIC_LEN 9 71 72 #if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) 73 struct read_lzop { 74 unsigned char *out_block; 75 size_t out_block_size; 76 int64_t total_out; 77 int flags; 78 uint32_t compressed_cksum; 79 uint32_t uncompressed_cksum; 80 size_t compressed_size; 81 size_t uncompressed_size; 82 size_t unconsumed_bytes; 83 char in_stream; 84 char eof; /* True = found end of compressed data. */ 85 }; 86 87 #define FILTER 0x0800 88 #define CRC32_HEADER 0x1000 89 #define EXTRA_FIELD 0x0040 90 #define ADLER32_UNCOMPRESSED 0x0001 91 #define ADLER32_COMPRESSED 0x0002 92 #define CRC32_UNCOMPRESSED 0x0100 93 #define CRC32_COMPRESSED 0x0200 94 #define MAX_BLOCK_SIZE (64 * 1024 * 1024) 95 96 static ssize_t lzop_filter_read(struct archive_read_filter *, const void **); 97 static int lzop_filter_close(struct archive_read_filter *); 98 #endif 99 100 static int lzop_bidder_bid(struct archive_read_filter_bidder *, 101 struct archive_read_filter *); 102 static int lzop_bidder_init(struct archive_read_filter *); 103 104 int 105 archive_read_support_filter_lzop(struct archive *_a) 106 { 107 struct archive_read *a = (struct archive_read *)_a; 108 struct archive_read_filter_bidder *reader; 109 110 archive_check_magic(_a, ARCHIVE_READ_MAGIC, 111 ARCHIVE_STATE_NEW, "archive_read_support_filter_lzop"); 112 113 if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK) 114 return (ARCHIVE_FATAL); 115 116 reader->data = NULL; 117 reader->bid = lzop_bidder_bid; 118 reader->init = lzop_bidder_init; 119 reader->options = NULL; 120 reader->free = NULL; 121 /* Signal the extent of lzop support with the return value here. */ 122 #if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) 123 return (ARCHIVE_OK); 124 #else 125 /* Return ARCHIVE_WARN since this always uses an external program. */ 126 archive_set_error(_a, ARCHIVE_ERRNO_MISC, 127 "Using external lzop program for lzop decompression"); 128 return (ARCHIVE_WARN); 129 #endif 130 } 131 132 /* 133 * Bidder just verifies the header and returns the number of verified bits. 134 */ 135 static int 136 lzop_bidder_bid(struct archive_read_filter_bidder *self, 137 struct archive_read_filter *filter) 138 { 139 const unsigned char *p; 140 ssize_t avail; 141 142 (void)self; /* UNUSED */ 143 144 p = __archive_read_filter_ahead(filter, LZOP_HEADER_MAGIC_LEN, &avail); 145 if (p == NULL || avail == 0) 146 return (0); 147 148 if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN)) 149 return (0); 150 151 return (LZOP_HEADER_MAGIC_LEN * 8); 152 } 153 154 #if !defined(HAVE_LZO_LZOCONF_H) || !defined(HAVE_LZO_LZO1X_H) 155 /* 156 * If we don't have the library on this system, we can't do the 157 * decompression directly. We can, however, try to run "lzop -d" 158 * in case that's available. 159 */ 160 static int 161 lzop_bidder_init(struct archive_read_filter *self) 162 { 163 int r; 164 165 r = __archive_read_program(self, "lzop -d"); 166 /* Note: We set the format here even if __archive_read_program() 167 * above fails. We do, after all, know what the format is 168 * even if we weren't able to read it. */ 169 self->code = ARCHIVE_FILTER_LZOP; 170 self->name = "lzop"; 171 return (r); 172 } 173 #else 174 /* 175 * Initialize the filter object. 176 */ 177 static int 178 lzop_bidder_init(struct archive_read_filter *self) 179 { 180 struct read_lzop *state; 181 182 self->code = ARCHIVE_FILTER_LZOP; 183 self->name = "lzop"; 184 185 state = (struct read_lzop *)calloc(sizeof(*state), 1); 186 if (state == NULL) { 187 archive_set_error(&self->archive->archive, ENOMEM, 188 "Can't allocate data for lzop decompression"); 189 return (ARCHIVE_FATAL); 190 } 191 192 self->data = state; 193 self->read = lzop_filter_read; 194 self->skip = NULL; /* not supported */ 195 self->close = lzop_filter_close; 196 197 return (ARCHIVE_OK); 198 } 199 200 static int 201 consume_header(struct archive_read_filter *self) 202 { 203 struct read_lzop *state = (struct read_lzop *)self->data; 204 const unsigned char *p, *_p; 205 unsigned checksum, flags, len, method, version; 206 207 /* 208 * Check LZOP magic code. 209 */ 210 p = __archive_read_filter_ahead(self->upstream, 211 LZOP_HEADER_MAGIC_LEN, NULL); 212 if (p == NULL) 213 return (ARCHIVE_EOF); 214 215 if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN)) 216 return (ARCHIVE_EOF); 217 __archive_read_filter_consume(self->upstream, 218 LZOP_HEADER_MAGIC_LEN); 219 220 p = __archive_read_filter_ahead(self->upstream, 29, NULL); 221 if (p == NULL) 222 goto truncated; 223 _p = p; 224 version = archive_be16dec(p); 225 p += 4;/* version(2 bytes) + library version(2 bytes) */ 226 227 if (version >= 0x940) { 228 unsigned reqversion = archive_be16dec(p); p += 2; 229 if (reqversion < 0x900) { 230 archive_set_error(&self->archive->archive, 231 ARCHIVE_ERRNO_MISC, "Invalid required version"); 232 return (ARCHIVE_FAILED); 233 } 234 } 235 236 method = *p++; 237 if (method < 1 || method > 3) { 238 archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, 239 "Unsupported method"); 240 return (ARCHIVE_FAILED); 241 } 242 243 if (version >= 0x940) { 244 unsigned level = *p++; 245 #if 0 246 unsigned default_level[] = {0, 3, 1, 9}; 247 #endif 248 if (level == 0) 249 /* Method is 1..3 here due to check above. */ 250 #if 0 /* Avoid an error Clang Static Analyzer claims 251 "Value stored to 'level' is never read". */ 252 level = default_level[method]; 253 #else 254 ;/* NOP */ 255 #endif 256 else if (level > 9) { 257 archive_set_error(&self->archive->archive, 258 ARCHIVE_ERRNO_MISC, "Invalid level"); 259 return (ARCHIVE_FAILED); 260 } 261 } 262 263 flags = archive_be32dec(p); p += 4; 264 265 if (flags & FILTER) 266 p += 4; /* Skip filter */ 267 p += 4; /* Skip mode */ 268 if (version >= 0x940) 269 p += 8; /* Skip mtime */ 270 else 271 p += 4; /* Skip mtime */ 272 len = *p++; /* Read filename length */ 273 len += p - _p; 274 /* Make sure we have all bytes we need to calculate checksum. */ 275 p = __archive_read_filter_ahead(self->upstream, len + 4, NULL); 276 if (p == NULL) 277 goto truncated; 278 if (flags & CRC32_HEADER) 279 checksum = crc32(crc32(0, NULL, 0), p, len); 280 else 281 checksum = adler32(adler32(0, NULL, 0), p, len); 282 if (archive_be32dec(p + len) != checksum) 283 goto corrupted; 284 __archive_read_filter_consume(self->upstream, len + 4); 285 if (flags & EXTRA_FIELD) { 286 /* Skip extra field */ 287 p = __archive_read_filter_ahead(self->upstream, 4, NULL); 288 if (p == NULL) 289 goto truncated; 290 len = archive_be32dec(p); 291 __archive_read_filter_consume(self->upstream, len + 4 + 4); 292 } 293 state->flags = flags; 294 state->in_stream = 1; 295 return (ARCHIVE_OK); 296 truncated: 297 archive_set_error(&self->archive->archive, 298 ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data"); 299 return (ARCHIVE_FAILED); 300 corrupted: 301 archive_set_error(&self->archive->archive, 302 ARCHIVE_ERRNO_FILE_FORMAT, "Corrupted lzop header"); 303 return (ARCHIVE_FAILED); 304 } 305 306 static int 307 consume_block_info(struct archive_read_filter *self) 308 { 309 struct read_lzop *state = (struct read_lzop *)self->data; 310 const unsigned char *p; 311 unsigned flags = state->flags; 312 313 p = __archive_read_filter_ahead(self->upstream, 4, NULL); 314 if (p == NULL) 315 goto truncated; 316 state->uncompressed_size = archive_be32dec(p); 317 __archive_read_filter_consume(self->upstream, 4); 318 if (state->uncompressed_size == 0) 319 return (ARCHIVE_EOF); 320 if (state->uncompressed_size > MAX_BLOCK_SIZE) 321 goto corrupted; 322 323 p = __archive_read_filter_ahead(self->upstream, 4, NULL); 324 if (p == NULL) 325 goto truncated; 326 state->compressed_size = archive_be32dec(p); 327 __archive_read_filter_consume(self->upstream, 4); 328 if (state->compressed_size > state->uncompressed_size) 329 goto corrupted; 330 331 if (flags & (CRC32_UNCOMPRESSED | ADLER32_UNCOMPRESSED)) { 332 p = __archive_read_filter_ahead(self->upstream, 4, NULL); 333 if (p == NULL) 334 goto truncated; 335 state->compressed_cksum = state->uncompressed_cksum = 336 archive_be32dec(p); 337 __archive_read_filter_consume(self->upstream, 4); 338 } 339 if ((flags & (CRC32_COMPRESSED | ADLER32_COMPRESSED)) && 340 state->compressed_size < state->uncompressed_size) { 341 p = __archive_read_filter_ahead(self->upstream, 4, NULL); 342 if (p == NULL) 343 goto truncated; 344 state->compressed_cksum = archive_be32dec(p); 345 __archive_read_filter_consume(self->upstream, 4); 346 } 347 return (ARCHIVE_OK); 348 truncated: 349 archive_set_error(&self->archive->archive, 350 ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data"); 351 return (ARCHIVE_FAILED); 352 corrupted: 353 archive_set_error(&self->archive->archive, 354 ARCHIVE_ERRNO_FILE_FORMAT, "Corrupted lzop header"); 355 return (ARCHIVE_FAILED); 356 } 357 358 static ssize_t 359 lzop_filter_read(struct archive_read_filter *self, const void **p) 360 { 361 struct read_lzop *state = (struct read_lzop *)self->data; 362 const void *b; 363 lzo_uint out_size; 364 uint32_t cksum; 365 int ret, r; 366 367 if (state->unconsumed_bytes) { 368 __archive_read_filter_consume(self->upstream, 369 state->unconsumed_bytes); 370 state->unconsumed_bytes = 0; 371 } 372 if (state->eof) 373 return (0); 374 375 for (;;) { 376 if (!state->in_stream) { 377 ret = consume_header(self); 378 if (ret < ARCHIVE_OK) 379 return (ret); 380 if (ret == ARCHIVE_EOF) { 381 state->eof = 1; 382 return (0); 383 } 384 } 385 ret = consume_block_info(self); 386 if (ret < ARCHIVE_OK) 387 return (ret); 388 if (ret == ARCHIVE_EOF) 389 state->in_stream = 0; 390 else 391 break; 392 } 393 394 if (state->out_block == NULL || 395 state->out_block_size < state->uncompressed_size) { 396 void *new_block; 397 398 new_block = realloc(state->out_block, state->uncompressed_size); 399 if (new_block == NULL) { 400 archive_set_error(&self->archive->archive, ENOMEM, 401 "Can't allocate data for lzop decompression"); 402 return (ARCHIVE_FATAL); 403 } 404 state->out_block = new_block; 405 state->out_block_size = state->uncompressed_size; 406 } 407 408 b = __archive_read_filter_ahead(self->upstream, 409 state->compressed_size, NULL); 410 if (b == NULL) { 411 archive_set_error(&self->archive->archive, 412 ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data"); 413 return (ARCHIVE_FATAL); 414 } 415 if (state->flags & CRC32_COMPRESSED) 416 cksum = crc32(crc32(0, NULL, 0), b, state->compressed_size); 417 else if (state->flags & ADLER32_COMPRESSED) 418 cksum = adler32(adler32(0, NULL, 0), b, state->compressed_size); 419 else 420 cksum = state->compressed_cksum; 421 if (cksum != state->compressed_cksum) { 422 archive_set_error(&self->archive->archive, 423 ARCHIVE_ERRNO_MISC, "Corrupted data"); 424 return (ARCHIVE_FATAL); 425 } 426 427 /* 428 * If the both uncompressed size and compressed size are the same, 429 * we do not decompress this block. 430 */ 431 if (state->uncompressed_size == state->compressed_size) { 432 *p = b; 433 state->total_out += state->compressed_size; 434 state->unconsumed_bytes = state->compressed_size; 435 return ((ssize_t)state->uncompressed_size); 436 } 437 438 /* 439 * Drive lzo uncompresison. 440 */ 441 out_size = (lzo_uint)state->uncompressed_size; 442 r = lzo1x_decompress_safe(b, (lzo_uint)state->compressed_size, 443 state->out_block, &out_size, NULL); 444 switch (r) { 445 case LZO_E_OK: 446 if (out_size == state->uncompressed_size) 447 break; 448 archive_set_error(&self->archive->archive, 449 ARCHIVE_ERRNO_MISC, "Corrupted data"); 450 return (ARCHIVE_FATAL); 451 case LZO_E_OUT_OF_MEMORY: 452 archive_set_error(&self->archive->archive, ENOMEM, 453 "lzop decompression failed: out of memory"); 454 return (ARCHIVE_FATAL); 455 default: 456 archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, 457 "lzop decompression failed: %d", r); 458 return (ARCHIVE_FATAL); 459 } 460 461 if (state->flags & CRC32_UNCOMPRESSED) 462 cksum = crc32(crc32(0, NULL, 0), state->out_block, 463 state->uncompressed_size); 464 else if (state->flags & ADLER32_UNCOMPRESSED) 465 cksum = adler32(adler32(0, NULL, 0), state->out_block, 466 state->uncompressed_size); 467 else 468 cksum = state->uncompressed_cksum; 469 if (cksum != state->uncompressed_cksum) { 470 archive_set_error(&self->archive->archive, 471 ARCHIVE_ERRNO_MISC, "Corrupted data"); 472 return (ARCHIVE_FATAL); 473 } 474 475 __archive_read_filter_consume(self->upstream, state->compressed_size); 476 *p = state->out_block; 477 state->total_out += out_size; 478 return ((ssize_t)out_size); 479 } 480 481 /* 482 * Clean up the decompressor. 483 */ 484 static int 485 lzop_filter_close(struct archive_read_filter *self) 486 { 487 struct read_lzop *state = (struct read_lzop *)self->data; 488 489 free(state->out_block); 490 free(state); 491 return (ARCHIVE_OK); 492 } 493 494 #endif 495