archive_read_support_format_rar.c revision 232153
1231200Smm/*- 2231200Smm* Copyright (c) 2003-2007 Tim Kientzle 3231200Smm* Copyright (c) 2011 Andres Mejia 4231200Smm* All rights reserved. 5231200Smm* 6231200Smm* Redistribution and use in source and binary forms, with or without 7231200Smm* modification, are permitted provided that the following conditions 8231200Smm* are met: 9231200Smm* 1. Redistributions of source code must retain the above copyright 10231200Smm* notice, this list of conditions and the following disclaimer. 11231200Smm* 2. Redistributions in binary form must reproduce the above copyright 12231200Smm* notice, this list of conditions and the following disclaimer in the 13231200Smm* documentation and/or other materials provided with the distribution. 14231200Smm* 15231200Smm* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16231200Smm* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17231200Smm* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18231200Smm* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19231200Smm* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20231200Smm* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21231200Smm* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22231200Smm* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23231200Smm* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24231200Smm* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25231200Smm*/ 26231200Smm 27231200Smm#include "archive_platform.h" 28231200Smm 29231200Smm#ifdef HAVE_ERRNO_H 30231200Smm#include <errno.h> 31231200Smm#endif 32231200Smm#include <time.h> 33231200Smm#include <limits.h> 34231200Smm#ifdef HAVE_ZLIB_H 35231200Smm#include <zlib.h> /* crc32 */ 36231200Smm#endif 37231200Smm 38231200Smm#include "archive.h" 39231200Smm#ifndef HAVE_ZLIB_H 40231200Smm#include "archive_crc32.h" 41231200Smm#endif 42231200Smm#include "archive_endian.h" 43231200Smm#include "archive_entry.h" 44231200Smm#include "archive_entry_locale.h" 45231200Smm#include "archive_ppmd7_private.h" 46231200Smm#include "archive_private.h" 47231200Smm#include "archive_read_private.h" 48231200Smm 49231200Smm/* RAR signature, also known as the mark header */ 50231200Smm#define RAR_SIGNATURE "\x52\x61\x72\x21\x1A\x07\x00" 51231200Smm 52231200Smm/* Header types */ 53231200Smm#define MARK_HEAD 0x72 54231200Smm#define MAIN_HEAD 0x73 55231200Smm#define FILE_HEAD 0x74 56231200Smm#define COMM_HEAD 0x75 57231200Smm#define AV_HEAD 0x76 58231200Smm#define SUB_HEAD 0x77 59231200Smm#define PROTECT_HEAD 0x78 60231200Smm#define SIGN_HEAD 0x79 61231200Smm#define NEWSUB_HEAD 0x7a 62231200Smm#define ENDARC_HEAD 0x7b 63231200Smm 64231200Smm/* Main Header Flags */ 65231200Smm#define MHD_VOLUME 0x0001 66231200Smm#define MHD_COMMENT 0x0002 67231200Smm#define MHD_LOCK 0x0004 68231200Smm#define MHD_SOLID 0x0008 69231200Smm#define MHD_NEWNUMBERING 0x0010 70231200Smm#define MHD_AV 0x0020 71231200Smm#define MHD_PROTECT 0x0040 72231200Smm#define MHD_PASSWORD 0x0080 73231200Smm#define MHD_FIRSTVOLUME 0x0100 74231200Smm#define MHD_ENCRYPTVER 0x0200 75231200Smm 76231200Smm/* Flags common to all headers */ 77231200Smm#define HD_MARKDELETION 0x4000 78231200Smm#define HD_ADD_SIZE_PRESENT 0x8000 79231200Smm 80231200Smm/* File Header Flags */ 81231200Smm#define FHD_SPLIT_BEFORE 0x0001 82231200Smm#define FHD_SPLIT_AFTER 0x0002 83231200Smm#define FHD_PASSWORD 0x0004 84231200Smm#define FHD_COMMENT 0x0008 85231200Smm#define FHD_SOLID 0x0010 86231200Smm#define FHD_LARGE 0x0100 87231200Smm#define FHD_UNICODE 0x0200 88231200Smm#define FHD_SALT 0x0400 89231200Smm#define FHD_VERSION 0x0800 90231200Smm#define FHD_EXTTIME 0x1000 91231200Smm#define FHD_EXTFLAGS 0x2000 92231200Smm 93231200Smm/* File dictionary sizes */ 94231200Smm#define DICTIONARY_SIZE_64 0x00 95231200Smm#define DICTIONARY_SIZE_128 0x20 96231200Smm#define DICTIONARY_SIZE_256 0x40 97231200Smm#define DICTIONARY_SIZE_512 0x60 98231200Smm#define DICTIONARY_SIZE_1024 0x80 99231200Smm#define DICTIONARY_SIZE_2048 0xA0 100231200Smm#define DICTIONARY_SIZE_4096 0xC0 101231200Smm#define FILE_IS_DIRECTORY 0xE0 102231200Smm#define DICTIONARY_MASK FILE_IS_DIRECTORY 103231200Smm 104231200Smm/* OS Flags */ 105231200Smm#define OS_MSDOS 0 106231200Smm#define OS_OS2 1 107231200Smm#define OS_WIN32 2 108231200Smm#define OS_UNIX 3 109231200Smm#define OS_MAC_OS 4 110231200Smm#define OS_BEOS 5 111231200Smm 112231200Smm/* Compression Methods */ 113231200Smm#define COMPRESS_METHOD_STORE 0x30 114231200Smm/* LZSS */ 115231200Smm#define COMPRESS_METHOD_FASTEST 0x31 116231200Smm#define COMPRESS_METHOD_FAST 0x32 117231200Smm#define COMPRESS_METHOD_NORMAL 0x33 118231200Smm/* PPMd Variant H */ 119231200Smm#define COMPRESS_METHOD_GOOD 0x34 120231200Smm#define COMPRESS_METHOD_BEST 0x35 121231200Smm 122231200Smm#define CRC_POLYNOMIAL 0xEDB88320 123231200Smm 124231200Smm#define NS_UNIT 10000000 125231200Smm 126231200Smm#define DICTIONARY_MAX_SIZE 0x400000 127231200Smm 128231200Smm#define MAINCODE_SIZE 299 129231200Smm#define OFFSETCODE_SIZE 60 130231200Smm#define LOWOFFSETCODE_SIZE 17 131231200Smm#define LENGTHCODE_SIZE 28 132231200Smm#define HUFFMAN_TABLE_SIZE \ 133231200Smm MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE + LENGTHCODE_SIZE 134231200Smm 135231200Smm#define MAX_SYMBOL_LENGTH 0xF 136231200Smm#define MAX_SYMBOLS 20 137231200Smm 138231200Smm/* 139231200Smm * Considering L1,L2 cache miss and a calling of write system-call, 140231200Smm * the best size of the output buffer(uncompressed buffer) is 128K. 141231200Smm * If the structure of extracting process is changed, this value 142231200Smm * might be researched again. 143231200Smm */ 144231200Smm#define UNP_BUFFER_SIZE (128 * 1024) 145231200Smm 146231200Smm/* Define this here for non-Windows platforms */ 147231200Smm#if !((defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)) 148231200Smm#define FILE_ATTRIBUTE_DIRECTORY 0x10 149231200Smm#endif 150231200Smm 151231200Smm/* Fields common to all headers */ 152231200Smmstruct rar_header 153231200Smm{ 154231200Smm char crc[2]; 155231200Smm char type; 156231200Smm char flags[2]; 157231200Smm char size[2]; 158231200Smm}; 159231200Smm 160231200Smm/* Fields common to all file headers */ 161231200Smmstruct rar_file_header 162231200Smm{ 163231200Smm char pack_size[4]; 164231200Smm char unp_size[4]; 165231200Smm char host_os; 166231200Smm char file_crc[4]; 167231200Smm char file_time[4]; 168231200Smm char unp_ver; 169231200Smm char method; 170231200Smm char name_size[2]; 171231200Smm char file_attr[4]; 172231200Smm}; 173231200Smm 174231200Smmstruct huffman_tree_node 175231200Smm{ 176231200Smm int branches[2]; 177231200Smm}; 178231200Smm 179231200Smmstruct huffman_table_entry 180231200Smm{ 181231200Smm unsigned int length; 182231200Smm int value; 183231200Smm}; 184231200Smm 185231200Smmstruct huffman_code 186231200Smm{ 187231200Smm struct huffman_tree_node *tree; 188231200Smm int numentries; 189231200Smm int minlength; 190231200Smm int maxlength; 191231200Smm int tablesize; 192231200Smm struct huffman_table_entry *table; 193231200Smm}; 194231200Smm 195231200Smmstruct lzss 196231200Smm{ 197231200Smm unsigned char *window; 198231200Smm int mask; 199231200Smm int64_t position; 200231200Smm}; 201231200Smm 202231200Smmstruct rar 203231200Smm{ 204231200Smm /* Entries from main RAR header */ 205231200Smm unsigned main_flags; 206231200Smm unsigned long file_crc; 207231200Smm char reserved1[2]; 208231200Smm char reserved2[4]; 209231200Smm char encryptver; 210231200Smm 211231200Smm /* File header entries */ 212231200Smm char compression_method; 213231200Smm unsigned file_flags; 214231200Smm int64_t packed_size; 215231200Smm int64_t unp_size; 216231200Smm time_t mtime; 217231200Smm long mnsec; 218231200Smm mode_t mode; 219231200Smm char *filename; 220231200Smm size_t filename_allocated; 221231200Smm 222231200Smm /* File header optional entries */ 223231200Smm char salt[8]; 224231200Smm time_t atime; 225231200Smm long ansec; 226231200Smm time_t ctime; 227231200Smm long cnsec; 228231200Smm time_t arctime; 229231200Smm long arcnsec; 230231200Smm 231231200Smm /* Fields to help with tracking decompression of files. */ 232231200Smm int64_t bytes_unconsumed; 233231200Smm int64_t bytes_remaining; 234231200Smm int64_t bytes_uncopied; 235231200Smm int64_t offset; 236231200Smm int64_t offset_outgoing; 237231200Smm char valid; 238231200Smm unsigned int unp_offset; 239231200Smm unsigned int unp_buffer_size; 240231200Smm unsigned char *unp_buffer; 241231200Smm unsigned int dictionary_size; 242231200Smm char start_new_block; 243231200Smm char entry_eof; 244231200Smm unsigned long crc_calculated; 245231200Smm int found_first_header; 246231200Smm 247231200Smm /* LZSS members */ 248231200Smm struct huffman_code maincode; 249231200Smm struct huffman_code offsetcode; 250231200Smm struct huffman_code lowoffsetcode; 251231200Smm struct huffman_code lengthcode; 252231200Smm unsigned char lengthtable[HUFFMAN_TABLE_SIZE]; 253231200Smm struct lzss lzss; 254231200Smm char output_last_match; 255231200Smm unsigned int lastlength; 256231200Smm unsigned int lastoffset; 257231200Smm unsigned int oldoffset[4]; 258231200Smm unsigned int lastlowoffset; 259231200Smm unsigned int numlowoffsetrepeats; 260231200Smm int64_t filterstart; 261231200Smm char start_new_table; 262231200Smm 263231200Smm /* PPMd Variant H members */ 264231200Smm char ppmd_valid; 265231200Smm char ppmd_eod; 266231200Smm char is_ppmd_block; 267231200Smm int ppmd_escape; 268231200Smm CPpmd7 ppmd7_context; 269231200Smm CPpmd7z_RangeDec range_dec; 270231200Smm IByteIn bytein; 271231200Smm 272231200Smm /* 273231200Smm * String conversion object. 274231200Smm */ 275231200Smm int init_default_conversion; 276231200Smm struct archive_string_conv *sconv_default; 277231200Smm struct archive_string_conv *opt_sconv; 278231200Smm struct archive_string_conv *sconv_utf8; 279231200Smm struct archive_string_conv *sconv_utf16be; 280231200Smm 281231200Smm /* 282231200Smm * Bit stream reader. 283231200Smm */ 284231200Smm struct rar_br { 285231200Smm#define CACHE_TYPE uint64_t 286231200Smm#define CACHE_BITS (8 * sizeof(CACHE_TYPE)) 287231200Smm /* Cache buffer. */ 288231200Smm CACHE_TYPE cache_buffer; 289231200Smm /* Indicates how many bits avail in cache_buffer. */ 290231200Smm int cache_avail; 291231200Smm ssize_t avail_in; 292231200Smm const unsigned char *next_in; 293231200Smm } br; 294231200Smm}; 295231200Smm 296231200Smmstatic int archive_read_format_rar_bid(struct archive_read *, int); 297231200Smmstatic int archive_read_format_rar_options(struct archive_read *, 298231200Smm const char *, const char *); 299231200Smmstatic int archive_read_format_rar_read_header(struct archive_read *, 300231200Smm struct archive_entry *); 301231200Smmstatic int archive_read_format_rar_read_data(struct archive_read *, 302231200Smm const void **, size_t *, int64_t *); 303231200Smmstatic int archive_read_format_rar_read_data_skip(struct archive_read *a); 304231200Smmstatic int archive_read_format_rar_cleanup(struct archive_read *); 305231200Smm 306231200Smm/* Support functions */ 307231200Smmstatic int read_header(struct archive_read *, struct archive_entry *, char); 308232153Smmstatic time_t get_time(int); 309231200Smmstatic int read_exttime(const char *, struct rar *, const char *); 310231200Smmstatic int read_symlink_stored(struct archive_read *, struct archive_entry *, 311231200Smm struct archive_string_conv *); 312231200Smmstatic int read_data_stored(struct archive_read *, const void **, size_t *, 313231200Smm int64_t *); 314231200Smmstatic int read_data_compressed(struct archive_read *, const void **, size_t *, 315231200Smm int64_t *); 316231200Smmstatic int rar_br_preparation(struct archive_read *, struct rar_br *); 317231200Smmstatic int parse_codes(struct archive_read *); 318231200Smmstatic void free_codes(struct archive_read *); 319231200Smmstatic int read_next_symbol(struct archive_read *, struct huffman_code *); 320231200Smmstatic int create_code(struct archive_read *, struct huffman_code *, 321231200Smm unsigned char *, int, char); 322231200Smmstatic int add_value(struct archive_read *, struct huffman_code *, int, int, 323231200Smm int); 324231200Smmstatic int new_node(struct huffman_code *); 325231200Smmstatic int make_table(struct archive_read *, struct huffman_code *); 326231200Smmstatic int make_table_recurse(struct archive_read *, struct huffman_code *, int, 327231200Smm struct huffman_table_entry *, int, int); 328231200Smmstatic int64_t expand(struct archive_read *, int64_t); 329231200Smmstatic int copy_from_lzss_window(struct archive_read *, const void **, 330231200Smm int64_t, int); 331231200Smm 332231200Smm/* 333231200Smm * Bit stream reader. 334231200Smm */ 335231200Smm/* Check that the cache buffer has enough bits. */ 336231200Smm#define rar_br_has(br, n) ((br)->cache_avail >= n) 337231200Smm/* Get compressed data by bit. */ 338231200Smm#define rar_br_bits(br, n) \ 339231200Smm (((uint32_t)((br)->cache_buffer >> \ 340231200Smm ((br)->cache_avail - (n)))) & cache_masks[n]) 341231200Smm#define rar_br_bits_forced(br, n) \ 342231200Smm (((uint32_t)((br)->cache_buffer << \ 343231200Smm ((n) - (br)->cache_avail))) & cache_masks[n]) 344231200Smm/* Read ahead to make sure the cache buffer has enough compressed data we 345231200Smm * will use. 346231200Smm * True : completed, there is enough data in the cache buffer. 347231200Smm * False : there is no data in the stream. */ 348231200Smm#define rar_br_read_ahead(a, br, n) \ 349231200Smm ((rar_br_has(br, (n)) || rar_br_fillup(a, br)) || rar_br_has(br, (n))) 350231200Smm/* Notify how many bits we consumed. */ 351231200Smm#define rar_br_consume(br, n) ((br)->cache_avail -= (n)) 352231200Smm#define rar_br_consume_unalined_bits(br) ((br)->cache_avail &= ~7) 353231200Smm 354231200Smmstatic const uint32_t cache_masks[] = { 355231200Smm 0x00000000, 0x00000001, 0x00000003, 0x00000007, 356231200Smm 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, 357231200Smm 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 358231200Smm 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 359231200Smm 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 360231200Smm 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 361231200Smm 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 362231200Smm 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 363231200Smm 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF 364231200Smm}; 365231200Smm 366231200Smm/* 367231200Smm * Shift away used bits in the cache data and fill it up with following bits. 368231200Smm * Call this when cache buffer does not have enough bits you need. 369231200Smm * 370231200Smm * Returns 1 if the cache buffer is full. 371231200Smm * Returns 0 if the cache buffer is not full; input buffer is empty. 372231200Smm */ 373231200Smmstatic int 374231200Smmrar_br_fillup(struct archive_read *a, struct rar_br *br) 375231200Smm{ 376231200Smm struct rar *rar = (struct rar *)(a->format->data); 377231200Smm int n = CACHE_BITS - br->cache_avail; 378231200Smm 379231200Smm for (;;) { 380231200Smm switch (n >> 3) { 381231200Smm case 8: 382231200Smm if (br->avail_in >= 8) { 383231200Smm br->cache_buffer = 384231200Smm ((uint64_t)br->next_in[0]) << 56 | 385231200Smm ((uint64_t)br->next_in[1]) << 48 | 386231200Smm ((uint64_t)br->next_in[2]) << 40 | 387231200Smm ((uint64_t)br->next_in[3]) << 32 | 388231200Smm ((uint32_t)br->next_in[4]) << 24 | 389231200Smm ((uint32_t)br->next_in[5]) << 16 | 390231200Smm ((uint32_t)br->next_in[6]) << 8 | 391231200Smm (uint32_t)br->next_in[7]; 392231200Smm br->next_in += 8; 393231200Smm br->avail_in -= 8; 394231200Smm br->cache_avail += 8 * 8; 395231200Smm rar->bytes_unconsumed += 8; 396231200Smm rar->bytes_remaining -= 8; 397231200Smm return (1); 398231200Smm } 399231200Smm break; 400231200Smm case 7: 401231200Smm if (br->avail_in >= 7) { 402231200Smm br->cache_buffer = 403231200Smm (br->cache_buffer << 56) | 404231200Smm ((uint64_t)br->next_in[0]) << 48 | 405231200Smm ((uint64_t)br->next_in[1]) << 40 | 406231200Smm ((uint64_t)br->next_in[2]) << 32 | 407231200Smm ((uint32_t)br->next_in[3]) << 24 | 408231200Smm ((uint32_t)br->next_in[4]) << 16 | 409231200Smm ((uint32_t)br->next_in[5]) << 8 | 410231200Smm (uint32_t)br->next_in[6]; 411231200Smm br->next_in += 7; 412231200Smm br->avail_in -= 7; 413231200Smm br->cache_avail += 7 * 8; 414231200Smm rar->bytes_unconsumed += 7; 415231200Smm rar->bytes_remaining -= 7; 416231200Smm return (1); 417231200Smm } 418231200Smm break; 419231200Smm case 6: 420231200Smm if (br->avail_in >= 6) { 421231200Smm br->cache_buffer = 422231200Smm (br->cache_buffer << 48) | 423231200Smm ((uint64_t)br->next_in[0]) << 40 | 424231200Smm ((uint64_t)br->next_in[1]) << 32 | 425231200Smm ((uint32_t)br->next_in[2]) << 24 | 426231200Smm ((uint32_t)br->next_in[3]) << 16 | 427231200Smm ((uint32_t)br->next_in[4]) << 8 | 428231200Smm (uint32_t)br->next_in[5]; 429231200Smm br->next_in += 6; 430231200Smm br->avail_in -= 6; 431231200Smm br->cache_avail += 6 * 8; 432231200Smm rar->bytes_unconsumed += 6; 433231200Smm rar->bytes_remaining -= 6; 434231200Smm return (1); 435231200Smm } 436231200Smm break; 437231200Smm case 0: 438231200Smm /* We have enough compressed data in 439231200Smm * the cache buffer.*/ 440231200Smm return (1); 441231200Smm default: 442231200Smm break; 443231200Smm } 444231200Smm if (br->avail_in <= 0) { 445231200Smm 446231200Smm if (rar->bytes_unconsumed > 0) { 447231200Smm /* Consume as much as the decompressor 448231200Smm * actually used. */ 449231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 450231200Smm rar->bytes_unconsumed = 0; 451231200Smm } 452231200Smm br->next_in = __archive_read_ahead(a, 1, &(br->avail_in)); 453231200Smm if (br->next_in == NULL) 454231200Smm return (0); 455231200Smm if (br->avail_in > rar->bytes_remaining) 456231200Smm br->avail_in = rar->bytes_remaining; 457231200Smm if (br->avail_in == 0) 458231200Smm return (0); 459231200Smm } 460231200Smm br->cache_buffer = 461231200Smm (br->cache_buffer << 8) | *br->next_in++; 462231200Smm br->avail_in--; 463231200Smm br->cache_avail += 8; 464231200Smm n -= 8; 465231200Smm rar->bytes_unconsumed++; 466231200Smm rar->bytes_remaining--; 467231200Smm } 468231200Smm} 469231200Smm 470231200Smmstatic int 471231200Smmrar_br_preparation(struct archive_read *a, struct rar_br *br) 472231200Smm{ 473231200Smm struct rar *rar = (struct rar *)(a->format->data); 474231200Smm 475231200Smm if (rar->bytes_remaining > 0) { 476231200Smm br->next_in = __archive_read_ahead(a, 1, &(br->avail_in)); 477231200Smm if (br->next_in == NULL) { 478231200Smm archive_set_error(&a->archive, 479231200Smm ARCHIVE_ERRNO_FILE_FORMAT, 480231200Smm "Truncated RAR file data"); 481231200Smm return (ARCHIVE_FATAL); 482231200Smm } 483231200Smm if (br->avail_in > rar->bytes_remaining) 484231200Smm br->avail_in = rar->bytes_remaining; 485231200Smm if (br->cache_avail == 0) 486231200Smm (void)rar_br_fillup(a, br); 487231200Smm } 488231200Smm return (ARCHIVE_OK); 489231200Smm} 490231200Smm 491231200Smm/* Find last bit set */ 492231200Smmstatic inline int 493231200Smmrar_fls(unsigned int word) 494231200Smm{ 495231200Smm word |= (word >> 1); 496231200Smm word |= (word >> 2); 497231200Smm word |= (word >> 4); 498231200Smm word |= (word >> 8); 499231200Smm word |= (word >> 16); 500231200Smm return word - (word >> 1); 501231200Smm} 502231200Smm 503231200Smm/* LZSS functions */ 504231200Smmstatic inline int64_t 505231200Smmlzss_position(struct lzss *lzss) 506231200Smm{ 507231200Smm return lzss->position; 508231200Smm} 509231200Smm 510231200Smmstatic inline int 511231200Smmlzss_mask(struct lzss *lzss) 512231200Smm{ 513231200Smm return lzss->mask; 514231200Smm} 515231200Smm 516231200Smmstatic inline int 517231200Smmlzss_size(struct lzss *lzss) 518231200Smm{ 519231200Smm return lzss->mask + 1; 520231200Smm} 521231200Smm 522231200Smmstatic inline int 523231200Smmlzss_offset_for_position(struct lzss *lzss, int64_t pos) 524231200Smm{ 525231200Smm return pos & lzss->mask; 526231200Smm} 527231200Smm 528231200Smmstatic inline unsigned char * 529231200Smmlzss_pointer_for_position(struct lzss *lzss, int64_t pos) 530231200Smm{ 531231200Smm return &lzss->window[lzss_offset_for_position(lzss, pos)]; 532231200Smm} 533231200Smm 534231200Smmstatic inline int 535231200Smmlzss_current_offset(struct lzss *lzss) 536231200Smm{ 537231200Smm return lzss_offset_for_position(lzss, lzss->position); 538231200Smm} 539231200Smm 540231200Smmstatic inline uint8_t * 541231200Smmlzss_current_pointer(struct lzss *lzss) 542231200Smm{ 543231200Smm return lzss_pointer_for_position(lzss, lzss->position); 544231200Smm} 545231200Smm 546231200Smmstatic inline void 547231200Smmlzss_emit_literal(struct rar *rar, uint8_t literal) 548231200Smm{ 549231200Smm *lzss_current_pointer(&rar->lzss) = literal; 550231200Smm rar->lzss.position++; 551231200Smm} 552231200Smm 553231200Smmstatic inline void 554231200Smmlzss_emit_match(struct rar *rar, int offset, int length) 555231200Smm{ 556231200Smm int dstoffs = lzss_current_offset(&rar->lzss); 557231200Smm int srcoffs = (dstoffs - offset) & lzss_mask(&rar->lzss); 558231200Smm int l, li, remaining; 559231200Smm unsigned char *d, *s; 560231200Smm 561231200Smm remaining = length; 562231200Smm while (remaining > 0) { 563231200Smm l = remaining; 564231200Smm if (dstoffs > srcoffs) { 565231200Smm if (l > lzss_size(&rar->lzss) - dstoffs) 566231200Smm l = lzss_size(&rar->lzss) - dstoffs; 567231200Smm } else { 568231200Smm if (l > lzss_size(&rar->lzss) - srcoffs) 569231200Smm l = lzss_size(&rar->lzss) - srcoffs; 570231200Smm } 571231200Smm d = &(rar->lzss.window[dstoffs]); 572231200Smm s = &(rar->lzss.window[srcoffs]); 573231200Smm if ((dstoffs + l < srcoffs) || (srcoffs + l < dstoffs)) 574231200Smm memcpy(d, s, l); 575231200Smm else { 576231200Smm for (li = 0; li < l; li++) 577231200Smm d[li] = s[li]; 578231200Smm } 579231200Smm remaining -= l; 580231200Smm dstoffs = (dstoffs + l) & lzss_mask(&(rar->lzss)); 581231200Smm srcoffs = (srcoffs + l) & lzss_mask(&(rar->lzss)); 582231200Smm } 583231200Smm rar->lzss.position += length; 584231200Smm} 585231200Smm 586231200Smmstatic void * 587231200Smmppmd_alloc(void *p, size_t size) 588231200Smm{ 589231200Smm (void)p; 590231200Smm return malloc(size); 591231200Smm} 592231200Smmstatic void 593231200Smmppmd_free(void *p, void *address) 594231200Smm{ 595231200Smm (void)p; 596231200Smm free(address); 597231200Smm} 598231200Smmstatic ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free }; 599231200Smm 600231200Smmstatic Byte 601231200Smmppmd_read(void *p) 602231200Smm{ 603231200Smm struct archive_read *a = ((IByteIn*)p)->a; 604231200Smm struct rar *rar = (struct rar *)(a->format->data); 605231200Smm struct rar_br *br = &(rar->br); 606231200Smm Byte b; 607231200Smm if (!rar_br_read_ahead(a, br, 8)) 608231200Smm { 609231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 610231200Smm "Truncated RAR file data"); 611231200Smm rar->valid = 0; 612231200Smm return 0; 613231200Smm } 614231200Smm b = rar_br_bits(br, 8); 615231200Smm rar_br_consume(br, 8); 616231200Smm return b; 617231200Smm} 618231200Smm 619231200Smmint 620231200Smmarchive_read_support_format_rar(struct archive *_a) 621231200Smm{ 622231200Smm struct archive_read *a = (struct archive_read *)_a; 623231200Smm struct rar *rar; 624231200Smm int r; 625231200Smm 626231200Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 627231200Smm "archive_read_support_format_rar"); 628231200Smm 629231200Smm rar = (struct rar *)malloc(sizeof(*rar)); 630231200Smm if (rar == NULL) 631231200Smm { 632231200Smm archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data"); 633231200Smm return (ARCHIVE_FATAL); 634231200Smm } 635231200Smm memset(rar, 0, sizeof(*rar)); 636231200Smm 637231200Smm r = __archive_read_register_format(a, 638231200Smm rar, 639231200Smm "rar", 640231200Smm archive_read_format_rar_bid, 641231200Smm archive_read_format_rar_options, 642231200Smm archive_read_format_rar_read_header, 643231200Smm archive_read_format_rar_read_data, 644231200Smm archive_read_format_rar_read_data_skip, 645231200Smm archive_read_format_rar_cleanup); 646231200Smm 647231200Smm if (r != ARCHIVE_OK) 648231200Smm free(rar); 649231200Smm return (r); 650231200Smm} 651231200Smm 652231200Smmstatic int 653231200Smmarchive_read_format_rar_bid(struct archive_read *a, int best_bid) 654231200Smm{ 655231200Smm const char *p; 656231200Smm 657231200Smm /* If there's already a bid > 30, we'll never win. */ 658231200Smm if (best_bid > 30) 659231200Smm return (-1); 660231200Smm 661231200Smm if ((p = __archive_read_ahead(a, 7, NULL)) == NULL) 662231200Smm return (-1); 663231200Smm 664231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) 665231200Smm return (30); 666231200Smm 667231200Smm if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) { 668231200Smm /* This is a PE file */ 669231200Smm ssize_t offset = 0x10000; 670231200Smm ssize_t window = 4096; 671231200Smm ssize_t bytes_avail; 672231200Smm while (offset + window <= (1024 * 128)) { 673231200Smm const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail); 674231200Smm if (buff == NULL) { 675231200Smm /* Remaining bytes are less than window. */ 676231200Smm window >>= 1; 677231200Smm if (window < 0x40) 678231200Smm return (0); 679231200Smm continue; 680231200Smm } 681231200Smm p = buff + offset; 682231200Smm while (p + 7 < buff + bytes_avail) { 683231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) 684231200Smm return (30); 685231200Smm p += 0x10; 686231200Smm } 687231200Smm offset = p - buff; 688231200Smm } 689231200Smm } 690231200Smm return (0); 691231200Smm} 692231200Smm 693231200Smmstatic int 694231200Smmskip_sfx(struct archive_read *a) 695231200Smm{ 696231200Smm const void *h; 697231200Smm const char *p, *q; 698231200Smm size_t skip, total; 699231200Smm ssize_t bytes, window; 700231200Smm 701231200Smm total = 0; 702231200Smm window = 4096; 703231200Smm while (total + window <= (1024 * 128)) { 704231200Smm h = __archive_read_ahead(a, window, &bytes); 705231200Smm if (h == NULL) { 706231200Smm /* Remaining bytes are less than window. */ 707231200Smm window >>= 1; 708231200Smm if (window < 0x40) 709231200Smm goto fatal; 710231200Smm continue; 711231200Smm } 712231200Smm if (bytes < 0x40) 713231200Smm goto fatal; 714231200Smm p = h; 715231200Smm q = p + bytes; 716231200Smm 717231200Smm /* 718231200Smm * Scan ahead until we find something that looks 719231200Smm * like the RAR header. 720231200Smm */ 721231200Smm while (p + 7 < q) { 722231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) { 723231200Smm skip = p - (const char *)h; 724231200Smm __archive_read_consume(a, skip); 725231200Smm return (ARCHIVE_OK); 726231200Smm } 727231200Smm p += 0x10; 728231200Smm } 729231200Smm skip = p - (const char *)h; 730231200Smm __archive_read_consume(a, skip); 731231200Smm total += skip; 732231200Smm } 733231200Smmfatal: 734231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 735231200Smm "Couldn't find out RAR header"); 736231200Smm return (ARCHIVE_FATAL); 737231200Smm} 738231200Smm 739231200Smmstatic int 740231200Smmarchive_read_format_rar_options(struct archive_read *a, 741231200Smm const char *key, const char *val) 742231200Smm{ 743231200Smm struct rar *rar; 744231200Smm int ret = ARCHIVE_FAILED; 745231200Smm 746231200Smm rar = (struct rar *)(a->format->data); 747231200Smm if (strcmp(key, "hdrcharset") == 0) { 748231200Smm if (val == NULL || val[0] == 0) 749231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 750231200Smm "rar: hdrcharset option needs a character-set name"); 751231200Smm else { 752231200Smm rar->opt_sconv = 753231200Smm archive_string_conversion_from_charset( 754231200Smm &a->archive, val, 0); 755231200Smm if (rar->opt_sconv != NULL) 756231200Smm ret = ARCHIVE_OK; 757231200Smm else 758231200Smm ret = ARCHIVE_FATAL; 759231200Smm } 760232153Smm return (ret); 761232153Smm } 762232153Smm 763232153Smm /* Note: The "warn" return is just to inform the options 764232153Smm * supervisor that we didn't handle it. It will generate 765232153Smm * a suitable error if no one used this option. */ 766232153Smm return (ARCHIVE_WARN); 767231200Smm} 768231200Smm 769231200Smmstatic int 770231200Smmarchive_read_format_rar_read_header(struct archive_read *a, 771231200Smm struct archive_entry *entry) 772231200Smm{ 773231200Smm const void *h; 774231200Smm const char *p; 775231200Smm struct rar *rar; 776231200Smm size_t skip; 777231200Smm char head_type; 778231200Smm int ret; 779231200Smm unsigned flags; 780231200Smm 781231200Smm a->archive.archive_format = ARCHIVE_FORMAT_RAR; 782231200Smm if (a->archive.archive_format_name == NULL) 783231200Smm a->archive.archive_format_name = "RAR"; 784231200Smm 785231200Smm rar = (struct rar *)(a->format->data); 786231200Smm 787231200Smm /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if 788231200Smm * this fails. 789231200Smm */ 790231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 791231200Smm return (ARCHIVE_EOF); 792231200Smm 793231200Smm p = h; 794231200Smm if (rar->found_first_header == 0 && 795231200Smm ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) { 796231200Smm /* This is an executable ? Must be self-extracting... */ 797231200Smm ret = skip_sfx(a); 798231200Smm if (ret < ARCHIVE_WARN) 799231200Smm return (ret); 800231200Smm } 801231200Smm rar->found_first_header = 1; 802231200Smm 803231200Smm while (1) 804231200Smm { 805231200Smm unsigned long crc32_val; 806231200Smm 807231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 808231200Smm return (ARCHIVE_FATAL); 809231200Smm p = h; 810231200Smm 811231200Smm head_type = p[2]; 812231200Smm switch(head_type) 813231200Smm { 814231200Smm case MARK_HEAD: 815231200Smm if (memcmp(p, RAR_SIGNATURE, 7) != 0) { 816231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 817231200Smm "Invalid marker header"); 818231200Smm return (ARCHIVE_FATAL); 819231200Smm } 820231200Smm __archive_read_consume(a, 7); 821231200Smm break; 822231200Smm 823231200Smm case MAIN_HEAD: 824231200Smm rar->main_flags = archive_le16dec(p + 3); 825231200Smm skip = archive_le16dec(p + 5); 826231200Smm if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) { 827231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 828231200Smm "Invalid header size"); 829231200Smm return (ARCHIVE_FATAL); 830231200Smm } 831231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 832231200Smm return (ARCHIVE_FATAL); 833231200Smm p = h; 834231200Smm memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1)); 835231200Smm memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1), 836231200Smm sizeof(rar->reserved2)); 837231200Smm if (rar->main_flags & MHD_ENCRYPTVER) { 838231200Smm if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) { 839231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 840231200Smm "Invalid header size"); 841231200Smm return (ARCHIVE_FATAL); 842231200Smm } 843231200Smm rar->encryptver = *(p + 7 + sizeof(rar->reserved1) + 844231200Smm sizeof(rar->reserved2)); 845231200Smm } 846231200Smm 847231200Smm if (rar->main_flags & MHD_VOLUME || 848231200Smm rar->main_flags & MHD_FIRSTVOLUME) 849231200Smm { 850231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 851231200Smm "RAR volume support unavailable."); 852231200Smm return (ARCHIVE_FATAL); 853231200Smm } 854231200Smm if (rar->main_flags & MHD_PASSWORD) 855231200Smm { 856231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 857231200Smm "RAR encryption support unavailable."); 858231200Smm return (ARCHIVE_FATAL); 859231200Smm } 860231200Smm 861231200Smm crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2); 862231200Smm if ((crc32_val & 0xffff) != archive_le16dec(p)) { 863231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 864231200Smm "Header CRC error"); 865231200Smm return (ARCHIVE_FATAL); 866231200Smm } 867231200Smm __archive_read_consume(a, skip); 868231200Smm break; 869231200Smm 870231200Smm case FILE_HEAD: 871231200Smm return read_header(a, entry, head_type); 872231200Smm 873231200Smm case COMM_HEAD: 874231200Smm case AV_HEAD: 875231200Smm case SUB_HEAD: 876231200Smm case PROTECT_HEAD: 877231200Smm case SIGN_HEAD: 878231200Smm flags = archive_le16dec(p + 3); 879231200Smm skip = archive_le16dec(p + 5); 880231200Smm if (skip < 7) { 881231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 882231200Smm "Invalid header size"); 883231200Smm return (ARCHIVE_FATAL); 884231200Smm } 885231200Smm if (skip > 7) { 886231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 887231200Smm return (ARCHIVE_FATAL); 888231200Smm p = h; 889231200Smm } 890231200Smm if (flags & HD_ADD_SIZE_PRESENT) 891231200Smm { 892231200Smm if (skip < 7 + 4) { 893231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 894231200Smm "Invalid header size"); 895231200Smm return (ARCHIVE_FATAL); 896231200Smm } 897231200Smm skip += archive_le32dec(p + 7); 898231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 899231200Smm return (ARCHIVE_FATAL); 900231200Smm p = h; 901231200Smm } 902231200Smm 903231200Smm crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2); 904231200Smm if ((crc32_val & 0xffff) != archive_le16dec(p)) { 905231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 906231200Smm "Header CRC error"); 907231200Smm return (ARCHIVE_FATAL); 908231200Smm } 909231200Smm __archive_read_consume(a, skip); 910231200Smm break; 911231200Smm 912231200Smm case NEWSUB_HEAD: 913231200Smm if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN) 914231200Smm return ret; 915231200Smm break; 916231200Smm 917231200Smm case ENDARC_HEAD: 918231200Smm return (ARCHIVE_EOF); 919231200Smm 920231200Smm default: 921231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 922231200Smm "Bad RAR file"); 923231200Smm return (ARCHIVE_FATAL); 924231200Smm } 925231200Smm } 926231200Smm} 927231200Smm 928231200Smmstatic int 929231200Smmarchive_read_format_rar_read_data(struct archive_read *a, const void **buff, 930231200Smm size_t *size, int64_t *offset) 931231200Smm{ 932231200Smm struct rar *rar = (struct rar *)(a->format->data); 933231200Smm int ret; 934231200Smm 935231200Smm if (rar->bytes_unconsumed > 0) { 936231200Smm /* Consume as much as the decompressor actually used. */ 937231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 938231200Smm rar->bytes_unconsumed = 0; 939231200Smm } 940231200Smm 941231200Smm if (rar->entry_eof) { 942231200Smm *buff = NULL; 943231200Smm *size = 0; 944231200Smm *offset = rar->offset; 945231200Smm return (ARCHIVE_EOF); 946231200Smm } 947231200Smm 948231200Smm switch (rar->compression_method) 949231200Smm { 950231200Smm case COMPRESS_METHOD_STORE: 951231200Smm ret = read_data_stored(a, buff, size, offset); 952231200Smm break; 953231200Smm 954231200Smm case COMPRESS_METHOD_FASTEST: 955231200Smm case COMPRESS_METHOD_FAST: 956231200Smm case COMPRESS_METHOD_NORMAL: 957231200Smm case COMPRESS_METHOD_GOOD: 958231200Smm case COMPRESS_METHOD_BEST: 959231200Smm ret = read_data_compressed(a, buff, size, offset); 960231200Smm if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) 961231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 962231200Smm break; 963231200Smm 964231200Smm default: 965231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 966231200Smm "Unsupported compression method for RAR file."); 967231200Smm ret = ARCHIVE_FATAL; 968231200Smm break; 969231200Smm } 970231200Smm return (ret); 971231200Smm} 972231200Smm 973231200Smmstatic int 974231200Smmarchive_read_format_rar_read_data_skip(struct archive_read *a) 975231200Smm{ 976231200Smm struct rar *rar; 977231200Smm int64_t bytes_skipped; 978231200Smm 979231200Smm rar = (struct rar *)(a->format->data); 980231200Smm 981231200Smm if (rar->bytes_unconsumed > 0) { 982231200Smm /* Consume as much as the decompressor actually used. */ 983231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 984231200Smm rar->bytes_unconsumed = 0; 985231200Smm } 986231200Smm 987231200Smm if (rar->bytes_remaining > 0) { 988231200Smm bytes_skipped = __archive_read_consume(a, rar->bytes_remaining); 989231200Smm if (bytes_skipped < 0) 990231200Smm return (ARCHIVE_FATAL); 991231200Smm } 992231200Smm return (ARCHIVE_OK); 993231200Smm} 994231200Smm 995231200Smmstatic int 996231200Smmarchive_read_format_rar_cleanup(struct archive_read *a) 997231200Smm{ 998231200Smm struct rar *rar; 999231200Smm 1000231200Smm rar = (struct rar *)(a->format->data); 1001231200Smm free_codes(a); 1002231200Smm free(rar->filename); 1003231200Smm free(rar->unp_buffer); 1004231200Smm free(rar->lzss.window); 1005231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 1006231200Smm free(rar); 1007231200Smm (a->format->data) = NULL; 1008231200Smm return (ARCHIVE_OK); 1009231200Smm} 1010231200Smm 1011231200Smmstatic int 1012231200Smmread_header(struct archive_read *a, struct archive_entry *entry, 1013231200Smm char head_type) 1014231200Smm{ 1015231200Smm const void *h; 1016231200Smm const char *p, *endp; 1017231200Smm struct rar *rar; 1018231200Smm struct rar_header rar_header; 1019231200Smm struct rar_file_header file_header; 1020231200Smm int64_t header_size; 1021231200Smm unsigned filename_size, end; 1022231200Smm char *filename; 1023231200Smm char *strp; 1024231200Smm char packed_size[8]; 1025231200Smm char unp_size[8]; 1026232153Smm int ttime; 1027231200Smm struct archive_string_conv *sconv, *fn_sconv; 1028231200Smm unsigned long crc32_val; 1029231200Smm int ret = (ARCHIVE_OK), ret2; 1030231200Smm 1031231200Smm rar = (struct rar *)(a->format->data); 1032231200Smm 1033231200Smm /* Setup a string conversion object for non-rar-unicode filenames. */ 1034231200Smm sconv = rar->opt_sconv; 1035231200Smm if (sconv == NULL) { 1036231200Smm if (!rar->init_default_conversion) { 1037231200Smm rar->sconv_default = 1038231200Smm archive_string_default_conversion_for_read( 1039231200Smm &(a->archive)); 1040231200Smm rar->init_default_conversion = 1; 1041231200Smm } 1042231200Smm sconv = rar->sconv_default; 1043231200Smm } 1044231200Smm 1045231200Smm 1046231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 1047231200Smm return (ARCHIVE_FATAL); 1048231200Smm p = h; 1049231200Smm memcpy(&rar_header, p, sizeof(rar_header)); 1050231200Smm rar->file_flags = archive_le16dec(rar_header.flags); 1051231200Smm header_size = archive_le16dec(rar_header.size); 1052232153Smm if (header_size < (int64_t)sizeof(file_header) + 7) { 1053231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1054231200Smm "Invalid header size"); 1055231200Smm return (ARCHIVE_FATAL); 1056231200Smm } 1057231200Smm crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2); 1058231200Smm __archive_read_consume(a, 7); 1059231200Smm 1060231200Smm if (!(rar->file_flags & FHD_SOLID)) 1061231200Smm { 1062231200Smm rar->compression_method = 0; 1063231200Smm rar->packed_size = 0; 1064231200Smm rar->unp_size = 0; 1065231200Smm rar->mtime = 0; 1066231200Smm rar->ctime = 0; 1067231200Smm rar->atime = 0; 1068231200Smm rar->arctime = 0; 1069231200Smm rar->mode = 0; 1070231200Smm memset(&rar->salt, 0, sizeof(rar->salt)); 1071231200Smm rar->atime = 0; 1072231200Smm rar->ansec = 0; 1073231200Smm rar->ctime = 0; 1074231200Smm rar->cnsec = 0; 1075231200Smm rar->mtime = 0; 1076231200Smm rar->mnsec = 0; 1077231200Smm rar->arctime = 0; 1078231200Smm rar->arcnsec = 0; 1079231200Smm } 1080231200Smm else 1081231200Smm { 1082231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1083231200Smm "RAR solid archive support unavailable."); 1084231200Smm return (ARCHIVE_FATAL); 1085231200Smm } 1086231200Smm 1087231200Smm if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL) 1088231200Smm return (ARCHIVE_FATAL); 1089231200Smm 1090231200Smm /* File Header CRC check. */ 1091231200Smm crc32_val = crc32(crc32_val, h, header_size - 7); 1092231200Smm if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) { 1093231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1094231200Smm "Header CRC error"); 1095231200Smm return (ARCHIVE_FATAL); 1096231200Smm } 1097231200Smm /* If no CRC error, Go on parsing File Header. */ 1098231200Smm p = h; 1099231200Smm endp = p + header_size - 7; 1100231200Smm memcpy(&file_header, p, sizeof(file_header)); 1101231200Smm p += sizeof(file_header); 1102231200Smm 1103231200Smm rar->compression_method = file_header.method; 1104231200Smm 1105232153Smm ttime = archive_le32dec(file_header.file_time); 1106232153Smm rar->mtime = get_time(ttime); 1107231200Smm 1108231200Smm rar->file_crc = archive_le32dec(file_header.file_crc); 1109231200Smm 1110231200Smm if (rar->file_flags & FHD_PASSWORD) 1111231200Smm { 1112231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1113231200Smm "RAR encryption support unavailable."); 1114231200Smm return (ARCHIVE_FATAL); 1115231200Smm } 1116231200Smm 1117231200Smm if (rar->file_flags & FHD_LARGE) 1118231200Smm { 1119231200Smm memcpy(packed_size, file_header.pack_size, 4); 1120231200Smm memcpy(packed_size + 4, p, 4); /* High pack size */ 1121231200Smm p += 4; 1122231200Smm memcpy(unp_size, file_header.unp_size, 4); 1123231200Smm memcpy(unp_size + 4, p, 4); /* High unpack size */ 1124231200Smm p += 4; 1125231200Smm rar->packed_size = archive_le64dec(&packed_size); 1126231200Smm rar->unp_size = archive_le64dec(&unp_size); 1127231200Smm } 1128231200Smm else 1129231200Smm { 1130231200Smm rar->packed_size = archive_le32dec(file_header.pack_size); 1131231200Smm rar->unp_size = archive_le32dec(file_header.unp_size); 1132231200Smm } 1133231200Smm 1134231200Smm /* TODO: Need to use CRC check for these kind of cases. 1135231200Smm * For now, check if sizes are not < 0. 1136231200Smm */ 1137231200Smm if (rar->packed_size < 0 || rar->unp_size < 0) 1138231200Smm { 1139231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1140231200Smm "Invalid sizes specified."); 1141231200Smm return (ARCHIVE_FATAL); 1142231200Smm } 1143231200Smm 1144231200Smm /* TODO: RARv3 subblocks contain comments. For now the complete block is 1145231200Smm * consumed at the end. 1146231200Smm */ 1147231200Smm if (head_type == NEWSUB_HEAD) { 1148231200Smm size_t distance = p - (const char *)h; 1149231200Smm header_size += rar->packed_size; 1150231200Smm /* Make sure we have the extended data. */ 1151231200Smm if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL) 1152231200Smm return (ARCHIVE_FATAL); 1153231200Smm p = h; 1154231200Smm endp = p + header_size - 7; 1155231200Smm p += distance; 1156231200Smm } 1157231200Smm 1158231200Smm filename_size = archive_le16dec(file_header.name_size); 1159231200Smm if (p + filename_size > endp) { 1160231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1161231200Smm "Invalid filename size"); 1162231200Smm return (ARCHIVE_FATAL); 1163231200Smm } 1164231200Smm if (rar->filename_allocated < filename_size+2) { 1165231200Smm rar->filename = realloc(rar->filename, filename_size+2); 1166231200Smm if (rar->filename == NULL) { 1167231200Smm archive_set_error(&a->archive, ENOMEM, 1168231200Smm "Couldn't allocate memory."); 1169231200Smm return (ARCHIVE_FATAL); 1170231200Smm } 1171231200Smm } 1172231200Smm filename = rar->filename; 1173231200Smm memcpy(filename, p, filename_size); 1174231200Smm filename[filename_size] = '\0'; 1175231200Smm if (rar->file_flags & FHD_UNICODE) 1176231200Smm { 1177231200Smm if (filename_size != strlen(filename)) 1178231200Smm { 1179231200Smm unsigned char highbyte, flagbits, flagbyte, length, offset; 1180231200Smm 1181231200Smm end = filename_size; 1182231200Smm filename_size = 0; 1183231200Smm offset = strlen(filename) + 1; 1184231200Smm highbyte = *(p + offset++); 1185231200Smm flagbits = 0; 1186231200Smm flagbyte = 0; 1187231200Smm while (offset < end && filename_size < end) 1188231200Smm { 1189231200Smm if (!flagbits) 1190231200Smm { 1191231200Smm flagbyte = *(p + offset++); 1192231200Smm flagbits = 8; 1193231200Smm } 1194231200Smm 1195231200Smm flagbits -= 2; 1196231200Smm switch((flagbyte >> flagbits) & 3) 1197231200Smm { 1198231200Smm case 0: 1199231200Smm filename[filename_size++] = '\0'; 1200231200Smm filename[filename_size++] = *(p + offset++); 1201231200Smm break; 1202231200Smm case 1: 1203231200Smm filename[filename_size++] = highbyte; 1204231200Smm filename[filename_size++] = *(p + offset++); 1205231200Smm break; 1206231200Smm case 2: 1207231200Smm filename[filename_size++] = *(p + offset + 1); 1208231200Smm filename[filename_size++] = *(p + offset); 1209231200Smm offset += 2; 1210231200Smm break; 1211231200Smm case 3: 1212231200Smm { 1213231200Smm length = *(p + offset++); 1214231200Smm while (length) 1215231200Smm { 1216231200Smm if (filename_size >= end) 1217231200Smm break; 1218231200Smm filename[filename_size++] = *(p + offset); 1219231200Smm length--; 1220231200Smm } 1221231200Smm } 1222231200Smm break; 1223231200Smm } 1224231200Smm } 1225231200Smm if (filename_size >= end) { 1226231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1227231200Smm "Invalid filename"); 1228231200Smm return (ARCHIVE_FATAL); 1229231200Smm } 1230231200Smm filename[filename_size++] = '\0'; 1231231200Smm filename[filename_size++] = '\0'; 1232231200Smm 1233231200Smm /* Decoded unicode form is UTF-16BE, so we have to update a string 1234231200Smm * conversion object for it. */ 1235231200Smm if (rar->sconv_utf16be == NULL) { 1236231200Smm rar->sconv_utf16be = archive_string_conversion_from_charset( 1237231200Smm &a->archive, "UTF-16BE", 1); 1238231200Smm if (rar->sconv_utf16be == NULL) 1239231200Smm return (ARCHIVE_FATAL); 1240231200Smm } 1241231200Smm fn_sconv = rar->sconv_utf16be; 1242231200Smm 1243231200Smm strp = filename; 1244231200Smm while (memcmp(strp, "\x00\x00", 2)) 1245231200Smm { 1246231200Smm if (!memcmp(strp, "\x00\\", 2)) 1247231200Smm *(strp + 1) = '/'; 1248231200Smm strp += 2; 1249231200Smm } 1250231200Smm p += offset; 1251231200Smm } else { 1252231200Smm /* 1253231200Smm * If FHD_UNICODE is set but no unicode data, this file name form 1254231200Smm * is UTF-8, so we have to update a string conversion object for 1255231200Smm * it accordingly. 1256231200Smm */ 1257231200Smm if (rar->sconv_utf8 == NULL) { 1258231200Smm rar->sconv_utf8 = archive_string_conversion_from_charset( 1259231200Smm &a->archive, "UTF-8", 1); 1260231200Smm if (rar->sconv_utf8 == NULL) 1261231200Smm return (ARCHIVE_FATAL); 1262231200Smm } 1263231200Smm fn_sconv = rar->sconv_utf8; 1264231200Smm while ((strp = strchr(filename, '\\')) != NULL) 1265231200Smm *strp = '/'; 1266231200Smm p += filename_size; 1267231200Smm } 1268231200Smm } 1269231200Smm else 1270231200Smm { 1271231200Smm fn_sconv = sconv; 1272231200Smm while ((strp = strchr(filename, '\\')) != NULL) 1273231200Smm *strp = '/'; 1274231200Smm p += filename_size; 1275231200Smm } 1276231200Smm 1277231200Smm if (rar->file_flags & FHD_SALT) 1278231200Smm { 1279231200Smm if (p + 8 > endp) { 1280231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1281231200Smm "Invalid header size"); 1282231200Smm return (ARCHIVE_FATAL); 1283231200Smm } 1284231200Smm memcpy(rar->salt, p, 8); 1285231200Smm p += 8; 1286231200Smm } 1287231200Smm 1288231200Smm if (rar->file_flags & FHD_EXTTIME) { 1289231200Smm if (read_exttime(p, rar, endp) < 0) { 1290231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1291231200Smm "Invalid header size"); 1292231200Smm return (ARCHIVE_FATAL); 1293231200Smm } 1294231200Smm } 1295231200Smm 1296231200Smm __archive_read_consume(a, header_size - 7); 1297231200Smm 1298231200Smm switch(file_header.host_os) 1299231200Smm { 1300231200Smm case OS_MSDOS: 1301231200Smm case OS_OS2: 1302231200Smm case OS_WIN32: 1303231200Smm rar->mode = archive_le32dec(file_header.file_attr); 1304231200Smm if (rar->mode & FILE_ATTRIBUTE_DIRECTORY) 1305231200Smm rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; 1306231200Smm else 1307231200Smm rar->mode = AE_IFREG; 1308231200Smm rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 1309231200Smm break; 1310231200Smm 1311231200Smm case OS_UNIX: 1312231200Smm case OS_MAC_OS: 1313231200Smm case OS_BEOS: 1314231200Smm rar->mode = archive_le32dec(file_header.file_attr); 1315231200Smm break; 1316231200Smm 1317231200Smm default: 1318231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1319231200Smm "Unknown file attributes from RAR file's host OS"); 1320231200Smm return (ARCHIVE_FATAL); 1321231200Smm } 1322231200Smm 1323231200Smm rar->bytes_remaining = rar->packed_size; 1324231200Smm rar->bytes_uncopied = rar->bytes_unconsumed = 0; 1325231200Smm rar->lzss.position = rar->dictionary_size = rar->offset = 0; 1326231200Smm rar->offset_outgoing = 0; 1327231200Smm rar->br.cache_avail = 0; 1328231200Smm rar->br.avail_in = 0; 1329231200Smm rar->crc_calculated = 0; 1330231200Smm rar->entry_eof = 0; 1331231200Smm rar->valid = 1; 1332231200Smm rar->is_ppmd_block = 0; 1333231200Smm rar->start_new_table = 1; 1334231200Smm free(rar->unp_buffer); 1335231200Smm rar->unp_buffer = NULL; 1336231200Smm rar->unp_offset = 0; 1337231200Smm rar->unp_buffer_size = UNP_BUFFER_SIZE; 1338231200Smm memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); 1339231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 1340231200Smm rar->ppmd_valid = rar->ppmd_eod = 0; 1341231200Smm 1342231200Smm /* Don't set any archive entries for non-file header types */ 1343231200Smm if (head_type == NEWSUB_HEAD) 1344231200Smm return ret; 1345231200Smm 1346231200Smm archive_entry_set_mtime(entry, rar->mtime, rar->mnsec); 1347231200Smm archive_entry_set_ctime(entry, rar->ctime, rar->cnsec); 1348231200Smm archive_entry_set_atime(entry, rar->atime, rar->ansec); 1349231200Smm archive_entry_set_size(entry, rar->unp_size); 1350231200Smm archive_entry_set_mode(entry, rar->mode); 1351231200Smm 1352231200Smm if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv)) 1353231200Smm { 1354231200Smm if (errno == ENOMEM) 1355231200Smm { 1356231200Smm archive_set_error(&a->archive, ENOMEM, 1357231200Smm "Can't allocate memory for Pathname"); 1358231200Smm return (ARCHIVE_FATAL); 1359231200Smm } 1360231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1361231200Smm "Pathname cannot be converted from %s to current locale.", 1362231200Smm archive_string_conversion_charset_name(fn_sconv)); 1363231200Smm ret = (ARCHIVE_WARN); 1364231200Smm } 1365231200Smm 1366231200Smm if (((rar->mode) & AE_IFMT) == AE_IFLNK) 1367231200Smm { 1368231200Smm /* Make sure a symbolic-link file does not have its body. */ 1369231200Smm rar->bytes_remaining = 0; 1370231200Smm archive_entry_set_size(entry, 0); 1371231200Smm 1372231200Smm /* Read a symbolic-link name. */ 1373231200Smm if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN)) 1374231200Smm return ret2; 1375231200Smm if (ret > ret2) 1376231200Smm ret = ret2; 1377231200Smm } 1378231200Smm 1379231200Smm if (rar->bytes_remaining == 0) 1380231200Smm rar->entry_eof = 1; 1381231200Smm 1382231200Smm return ret; 1383231200Smm} 1384231200Smm 1385231200Smmstatic time_t 1386232153Smmget_time(int ttime) 1387231200Smm{ 1388231200Smm struct tm tm; 1389232153Smm tm.tm_sec = 2 * (ttime & 0x1f); 1390232153Smm tm.tm_min = (ttime >> 5) & 0x3f; 1391232153Smm tm.tm_hour = (ttime >> 11) & 0x1f; 1392232153Smm tm.tm_mday = (ttime >> 16) & 0x1f; 1393232153Smm tm.tm_mon = ((ttime >> 21) & 0x0f) - 1; 1394232153Smm tm.tm_year = ((ttime >> 25) & 0x7f) + 80; 1395231200Smm tm.tm_isdst = -1; 1396231200Smm return mktime(&tm); 1397231200Smm} 1398231200Smm 1399231200Smmstatic int 1400231200Smmread_exttime(const char *p, struct rar *rar, const char *endp) 1401231200Smm{ 1402231200Smm unsigned rmode, flags, rem, j, count; 1403232153Smm int ttime, i; 1404231200Smm struct tm *tm; 1405231200Smm time_t t; 1406231200Smm long nsec; 1407231200Smm 1408231200Smm if (p + 2 > endp) 1409231200Smm return (-1); 1410231200Smm flags = archive_le16dec(p); 1411231200Smm p += 2; 1412231200Smm 1413231200Smm for (i = 3; i >= 0; i--) 1414231200Smm { 1415231200Smm t = 0; 1416231200Smm if (i == 3) 1417231200Smm t = rar->mtime; 1418231200Smm rmode = flags >> i * 4; 1419231200Smm if (rmode & 8) 1420231200Smm { 1421231200Smm if (!t) 1422231200Smm { 1423231200Smm if (p + 4 > endp) 1424231200Smm return (-1); 1425232153Smm ttime = archive_le32dec(p); 1426232153Smm t = get_time(ttime); 1427231200Smm p += 4; 1428231200Smm } 1429231200Smm rem = 0; 1430231200Smm count = rmode & 3; 1431231200Smm if (p + count > endp) 1432231200Smm return (-1); 1433231200Smm for (j = 0; j < count; j++) 1434231200Smm { 1435231200Smm rem = ((*p) << 16) | (rem >> 8); 1436231200Smm p++; 1437231200Smm } 1438231200Smm tm = localtime(&t); 1439231200Smm nsec = tm->tm_sec + rem / NS_UNIT; 1440231200Smm if (rmode & 4) 1441231200Smm { 1442231200Smm tm->tm_sec++; 1443231200Smm t = mktime(tm); 1444231200Smm } 1445231200Smm if (i == 3) 1446231200Smm { 1447231200Smm rar->mtime = t; 1448231200Smm rar->mnsec = nsec; 1449231200Smm } 1450231200Smm else if (i == 2) 1451231200Smm { 1452231200Smm rar->ctime = t; 1453231200Smm rar->cnsec = nsec; 1454231200Smm } 1455231200Smm else if (i == 1) 1456231200Smm { 1457231200Smm rar->atime = t; 1458231200Smm rar->ansec = nsec; 1459231200Smm } 1460231200Smm else 1461231200Smm { 1462231200Smm rar->arctime = t; 1463231200Smm rar->arcnsec = nsec; 1464231200Smm } 1465231200Smm } 1466231200Smm } 1467231200Smm return (0); 1468231200Smm} 1469231200Smm 1470231200Smmstatic int 1471231200Smmread_symlink_stored(struct archive_read *a, struct archive_entry *entry, 1472231200Smm struct archive_string_conv *sconv) 1473231200Smm{ 1474231200Smm const void *h; 1475231200Smm const char *p; 1476231200Smm struct rar *rar; 1477231200Smm int ret = (ARCHIVE_OK); 1478231200Smm 1479231200Smm rar = (struct rar *)(a->format->data); 1480231200Smm if ((h = __archive_read_ahead(a, rar->packed_size, NULL)) == NULL) 1481231200Smm return (ARCHIVE_FATAL); 1482231200Smm p = h; 1483231200Smm 1484231200Smm if (archive_entry_copy_symlink_l(entry, p, rar->packed_size, sconv)) 1485231200Smm { 1486231200Smm if (errno == ENOMEM) 1487231200Smm { 1488231200Smm archive_set_error(&a->archive, ENOMEM, 1489231200Smm "Can't allocate memory for link"); 1490231200Smm return (ARCHIVE_FATAL); 1491231200Smm } 1492231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1493231200Smm "link cannot be converted from %s to current locale.", 1494231200Smm archive_string_conversion_charset_name(sconv)); 1495231200Smm ret = (ARCHIVE_WARN); 1496231200Smm } 1497231200Smm __archive_read_consume(a, rar->packed_size); 1498231200Smm return ret; 1499231200Smm} 1500231200Smm 1501231200Smmstatic int 1502231200Smmread_data_stored(struct archive_read *a, const void **buff, size_t *size, 1503231200Smm int64_t *offset) 1504231200Smm{ 1505231200Smm struct rar *rar; 1506231200Smm ssize_t bytes_avail; 1507231200Smm 1508231200Smm rar = (struct rar *)(a->format->data); 1509231200Smm if (rar->bytes_remaining == 0) 1510231200Smm { 1511231200Smm *buff = NULL; 1512231200Smm *size = 0; 1513231200Smm *offset = rar->offset; 1514231200Smm if (rar->file_crc != rar->crc_calculated) { 1515231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1516231200Smm "File CRC error"); 1517231200Smm return (ARCHIVE_FATAL); 1518231200Smm } 1519231200Smm rar->entry_eof = 1; 1520231200Smm return (ARCHIVE_EOF); 1521231200Smm } 1522231200Smm 1523231200Smm *buff = __archive_read_ahead(a, 1, &bytes_avail); 1524231200Smm if (bytes_avail <= 0) 1525231200Smm { 1526231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1527231200Smm "Truncated RAR file data"); 1528231200Smm return (ARCHIVE_FATAL); 1529231200Smm } 1530231200Smm if (bytes_avail > rar->bytes_remaining) 1531231200Smm bytes_avail = rar->bytes_remaining; 1532231200Smm 1533231200Smm *size = bytes_avail; 1534231200Smm *offset = rar->offset; 1535231200Smm rar->offset += bytes_avail; 1536231200Smm rar->bytes_remaining -= bytes_avail; 1537231200Smm rar->bytes_unconsumed = bytes_avail; 1538231200Smm /* Calculate File CRC. */ 1539231200Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, bytes_avail); 1540231200Smm return (ARCHIVE_OK); 1541231200Smm} 1542231200Smm 1543231200Smmstatic int 1544231200Smmread_data_compressed(struct archive_read *a, const void **buff, size_t *size, 1545231200Smm int64_t *offset) 1546231200Smm{ 1547231200Smm struct rar *rar; 1548231200Smm int64_t start, end, actualend; 1549231200Smm size_t bs; 1550231200Smm int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i; 1551231200Smm 1552231200Smm rar = (struct rar *)(a->format->data); 1553231200Smm 1554231200Smm do { 1555231200Smm if (!rar->valid) 1556231200Smm return (ARCHIVE_FATAL); 1557231200Smm if (rar->ppmd_eod || 1558231200Smm (rar->dictionary_size && rar->offset >= rar->unp_size)) 1559231200Smm { 1560231200Smm if (rar->unp_offset > 0) { 1561231200Smm /* 1562231200Smm * We have unprocessed extracted data. write it out. 1563231200Smm */ 1564231200Smm *buff = rar->unp_buffer; 1565231200Smm *size = rar->unp_offset; 1566231200Smm *offset = rar->offset_outgoing; 1567231200Smm rar->offset_outgoing += *size; 1568231200Smm /* Calculate File CRC. */ 1569231200Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size); 1570231200Smm rar->unp_offset = 0; 1571231200Smm return (ARCHIVE_OK); 1572231200Smm } 1573231200Smm *buff = NULL; 1574231200Smm *size = 0; 1575231200Smm *offset = rar->offset; 1576231200Smm if (rar->file_crc != rar->crc_calculated) { 1577231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1578231200Smm "File CRC error"); 1579231200Smm return (ARCHIVE_FATAL); 1580231200Smm } 1581231200Smm rar->entry_eof = 1; 1582231200Smm return (ARCHIVE_EOF); 1583231200Smm } 1584231200Smm 1585231200Smm if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0) 1586231200Smm { 1587231200Smm if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) 1588231200Smm bs = rar->unp_buffer_size - rar->unp_offset; 1589231200Smm else 1590231200Smm bs = rar->bytes_uncopied; 1591231200Smm ret = copy_from_lzss_window(a, buff, rar->offset, bs); 1592231200Smm if (ret != ARCHIVE_OK) 1593231200Smm return (ret); 1594231200Smm rar->offset += bs; 1595231200Smm rar->bytes_uncopied -= bs; 1596231200Smm if (*buff != NULL) { 1597231200Smm rar->unp_offset = 0; 1598231200Smm *size = rar->unp_buffer_size; 1599231200Smm *offset = rar->offset_outgoing; 1600231200Smm rar->offset_outgoing += *size; 1601231200Smm /* Calculate File CRC. */ 1602231200Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size); 1603231200Smm return (ret); 1604231200Smm } 1605231200Smm continue; 1606231200Smm } 1607231200Smm 1608231200Smm if (!rar->br.next_in && 1609231200Smm (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN) 1610231200Smm return (ret); 1611231200Smm if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN))) 1612231200Smm return (ret); 1613231200Smm 1614231200Smm if (rar->is_ppmd_block) 1615231200Smm { 1616231200Smm if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1617231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1618231200Smm { 1619231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1620231200Smm "Invalid symbol"); 1621231200Smm return (ARCHIVE_FATAL); 1622231200Smm } 1623231200Smm if(sym != rar->ppmd_escape) 1624231200Smm { 1625231200Smm lzss_emit_literal(rar, sym); 1626231200Smm rar->bytes_uncopied++; 1627231200Smm } 1628231200Smm else 1629231200Smm { 1630231200Smm if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1631231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1632231200Smm { 1633231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1634231200Smm "Invalid symbol"); 1635231200Smm return (ARCHIVE_FATAL); 1636231200Smm } 1637231200Smm 1638231200Smm switch(code) 1639231200Smm { 1640231200Smm case 0: 1641231200Smm rar->start_new_table = 1; 1642231200Smm return read_data_compressed(a, buff, size, offset); 1643231200Smm 1644231200Smm case 2: 1645231200Smm rar->ppmd_eod = 1;/* End Of ppmd Data. */ 1646231200Smm continue; 1647231200Smm 1648231200Smm case 3: 1649231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1650231200Smm "Parsing filters is unsupported."); 1651231200Smm return (ARCHIVE_FAILED); 1652231200Smm 1653231200Smm case 4: 1654231200Smm lzss_offset = 0; 1655231200Smm for (i = 2; i >= 0; i--) 1656231200Smm { 1657231200Smm if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1658231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1659231200Smm { 1660231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1661231200Smm "Invalid symbol"); 1662231200Smm return (ARCHIVE_FATAL); 1663231200Smm } 1664231200Smm lzss_offset |= code << (i * 8); 1665231200Smm } 1666231200Smm if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1667231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1668231200Smm { 1669231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1670231200Smm "Invalid symbol"); 1671231200Smm return (ARCHIVE_FATAL); 1672231200Smm } 1673231200Smm lzss_emit_match(rar, lzss_offset + 2, length + 32); 1674231200Smm rar->bytes_uncopied += length + 32; 1675231200Smm break; 1676231200Smm 1677231200Smm case 5: 1678231200Smm if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1679231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1680231200Smm { 1681231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1682231200Smm "Invalid symbol"); 1683231200Smm return (ARCHIVE_FATAL); 1684231200Smm } 1685231200Smm lzss_emit_match(rar, 1, length + 4); 1686231200Smm rar->bytes_uncopied += length + 4; 1687231200Smm break; 1688231200Smm 1689231200Smm default: 1690231200Smm lzss_emit_literal(rar, sym); 1691231200Smm rar->bytes_uncopied++; 1692231200Smm } 1693231200Smm } 1694231200Smm } 1695231200Smm else 1696231200Smm { 1697231200Smm start = rar->offset; 1698231200Smm end = start + rar->dictionary_size; 1699231200Smm rar->filterstart = INT64_MAX; 1700231200Smm 1701231200Smm if ((actualend = expand(a, end)) < 0) 1702231200Smm return ((int)actualend); 1703231200Smm 1704231200Smm rar->bytes_uncopied = actualend - start; 1705231200Smm if (rar->bytes_uncopied == 0) { 1706231200Smm /* Broken RAR files cause this case. 1707231200Smm * NOTE: If this case were possible on a normal RAR file 1708231200Smm * we would find out where it was actually bad and 1709231200Smm * what we would do to solve it. */ 1710231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1711231200Smm "Internal error extracting RAR file"); 1712231200Smm return (ARCHIVE_FATAL); 1713231200Smm } 1714231200Smm } 1715231200Smm if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) 1716231200Smm bs = rar->unp_buffer_size - rar->unp_offset; 1717231200Smm else 1718231200Smm bs = rar->bytes_uncopied; 1719231200Smm ret = copy_from_lzss_window(a, buff, rar->offset, bs); 1720231200Smm if (ret != ARCHIVE_OK) 1721231200Smm return (ret); 1722231200Smm rar->offset += bs; 1723231200Smm rar->bytes_uncopied -= bs; 1724231200Smm /* 1725231200Smm * If *buff is NULL, it means unp_buffer is not full. 1726231200Smm * So we have to continue extracting a RAR file. 1727231200Smm */ 1728231200Smm } while (*buff == NULL); 1729231200Smm 1730231200Smm rar->unp_offset = 0; 1731231200Smm *size = rar->unp_buffer_size; 1732231200Smm *offset = rar->offset_outgoing; 1733231200Smm rar->offset_outgoing += *size; 1734231200Smm /* Calculate File CRC. */ 1735231200Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size); 1736231200Smm return ret; 1737231200Smm} 1738231200Smm 1739231200Smmstatic int 1740231200Smmparse_codes(struct archive_read *a) 1741231200Smm{ 1742231200Smm int i, j, val, n, r; 1743231200Smm unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags; 1744231200Smm unsigned int maxorder; 1745231200Smm struct huffman_code precode; 1746231200Smm struct rar *rar = (struct rar *)(a->format->data); 1747231200Smm struct rar_br *br = &(rar->br); 1748231200Smm 1749231200Smm free_codes(a); 1750231200Smm 1751231200Smm /* Skip to the next byte */ 1752231200Smm rar_br_consume_unalined_bits(br); 1753231200Smm 1754231200Smm /* PPMd block flag */ 1755231200Smm if (!rar_br_read_ahead(a, br, 1)) 1756231200Smm goto truncated_data; 1757231200Smm if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0) 1758231200Smm { 1759231200Smm rar_br_consume(br, 1); 1760231200Smm if (!rar_br_read_ahead(a, br, 7)) 1761231200Smm goto truncated_data; 1762231200Smm ppmd_flags = rar_br_bits(br, 7); 1763231200Smm rar_br_consume(br, 7); 1764231200Smm 1765231200Smm /* Memory is allocated in MB */ 1766231200Smm if (ppmd_flags & 0x20) 1767231200Smm { 1768231200Smm if (!rar_br_read_ahead(a, br, 8)) 1769231200Smm goto truncated_data; 1770231200Smm rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20; 1771231200Smm rar_br_consume(br, 8); 1772231200Smm } 1773231200Smm 1774231200Smm if (ppmd_flags & 0x40) 1775231200Smm { 1776231200Smm if (!rar_br_read_ahead(a, br, 8)) 1777231200Smm goto truncated_data; 1778231200Smm rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8); 1779231200Smm rar_br_consume(br, 8); 1780231200Smm } 1781231200Smm else 1782231200Smm rar->ppmd_escape = 2; 1783231200Smm 1784231200Smm if (ppmd_flags & 0x20) 1785231200Smm { 1786231200Smm maxorder = (ppmd_flags & 0x1F) + 1; 1787231200Smm if(maxorder > 16) 1788231200Smm maxorder = 16 + (maxorder - 16) * 3; 1789231200Smm 1790231200Smm if (maxorder == 1) 1791231200Smm { 1792231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1793231200Smm "Truncated RAR file data"); 1794231200Smm return (ARCHIVE_FATAL); 1795231200Smm } 1796231200Smm 1797231200Smm /* Make sure ppmd7_contest is freed before Ppmd7_Construct 1798231200Smm * because reading a broken file cause this abnormal sequence. */ 1799231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 1800231200Smm 1801231200Smm rar->bytein.a = a; 1802231200Smm rar->bytein.Read = &ppmd_read; 1803231200Smm __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec); 1804231200Smm rar->range_dec.Stream = &rar->bytein; 1805231200Smm __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context); 1806231200Smm 1807231200Smm if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context, 1808231200Smm rar->dictionary_size, &g_szalloc)) 1809231200Smm { 1810231200Smm archive_set_error(&a->archive, ENOMEM, 1811231200Smm "Out of memory"); 1812231200Smm return (ARCHIVE_FATAL); 1813231200Smm } 1814231200Smm if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) 1815231200Smm { 1816231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1817231200Smm "Unable to initialize PPMd range decoder"); 1818231200Smm return (ARCHIVE_FATAL); 1819231200Smm } 1820231200Smm __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder); 1821231200Smm rar->ppmd_valid = 1; 1822231200Smm } 1823231200Smm else 1824231200Smm { 1825231200Smm if (!rar->ppmd_valid) { 1826231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1827231200Smm "Invalid PPMd sequence"); 1828231200Smm return (ARCHIVE_FATAL); 1829231200Smm } 1830231200Smm if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) 1831231200Smm { 1832231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1833231200Smm "Unable to initialize PPMd range decoder"); 1834231200Smm return (ARCHIVE_FATAL); 1835231200Smm } 1836231200Smm } 1837231200Smm } 1838231200Smm else 1839231200Smm { 1840231200Smm rar_br_consume(br, 1); 1841231200Smm 1842231200Smm /* Keep existing table flag */ 1843231200Smm if (!rar_br_read_ahead(a, br, 1)) 1844231200Smm goto truncated_data; 1845231200Smm if (!rar_br_bits(br, 1)) 1846231200Smm memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); 1847231200Smm rar_br_consume(br, 1); 1848231200Smm 1849231200Smm memset(&bitlengths, 0, sizeof(bitlengths)); 1850231200Smm for (i = 0; i < MAX_SYMBOLS;) 1851231200Smm { 1852231200Smm if (!rar_br_read_ahead(a, br, 4)) 1853231200Smm goto truncated_data; 1854231200Smm bitlengths[i++] = rar_br_bits(br, 4); 1855231200Smm rar_br_consume(br, 4); 1856231200Smm if (bitlengths[i-1] == 0xF) 1857231200Smm { 1858231200Smm if (!rar_br_read_ahead(a, br, 4)) 1859231200Smm goto truncated_data; 1860231200Smm zerocount = rar_br_bits(br, 4); 1861231200Smm rar_br_consume(br, 4); 1862231200Smm if (zerocount) 1863231200Smm { 1864231200Smm i--; 1865231200Smm for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++) 1866231200Smm bitlengths[i++] = 0; 1867231200Smm } 1868231200Smm } 1869231200Smm } 1870231200Smm 1871231200Smm memset(&precode, 0, sizeof(precode)); 1872231200Smm r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH); 1873231200Smm if (r != ARCHIVE_OK) { 1874231200Smm free(precode.tree); 1875231200Smm free(precode.table); 1876231200Smm return (r); 1877231200Smm } 1878231200Smm 1879231200Smm for (i = 0; i < HUFFMAN_TABLE_SIZE;) 1880231200Smm { 1881231200Smm if ((val = read_next_symbol(a, &precode)) < 0) { 1882231200Smm free(precode.tree); 1883231200Smm free(precode.table); 1884231200Smm return (ARCHIVE_FATAL); 1885231200Smm } 1886231200Smm if (val < 16) 1887231200Smm { 1888231200Smm rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF; 1889231200Smm i++; 1890231200Smm } 1891231200Smm else if (val < 18) 1892231200Smm { 1893231200Smm if (i == 0) 1894231200Smm { 1895231200Smm free(precode.tree); 1896231200Smm free(precode.table); 1897231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1898231200Smm "Internal error extracting RAR file."); 1899231200Smm return (ARCHIVE_FATAL); 1900231200Smm } 1901231200Smm 1902231200Smm if(val == 16) { 1903231200Smm if (!rar_br_read_ahead(a, br, 3)) { 1904231200Smm free(precode.tree); 1905231200Smm free(precode.table); 1906231200Smm goto truncated_data; 1907231200Smm } 1908231200Smm n = rar_br_bits(br, 3) + 3; 1909231200Smm rar_br_consume(br, 3); 1910231200Smm } else { 1911231200Smm if (!rar_br_read_ahead(a, br, 7)) { 1912231200Smm free(precode.tree); 1913231200Smm free(precode.table); 1914231200Smm goto truncated_data; 1915231200Smm } 1916231200Smm n = rar_br_bits(br, 7) + 11; 1917231200Smm rar_br_consume(br, 7); 1918231200Smm } 1919231200Smm 1920231200Smm for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) 1921231200Smm { 1922231200Smm rar->lengthtable[i] = rar->lengthtable[i-1]; 1923231200Smm i++; 1924231200Smm } 1925231200Smm } 1926231200Smm else 1927231200Smm { 1928231200Smm if(val == 18) { 1929231200Smm if (!rar_br_read_ahead(a, br, 3)) { 1930231200Smm free(precode.tree); 1931231200Smm free(precode.table); 1932231200Smm goto truncated_data; 1933231200Smm } 1934231200Smm n = rar_br_bits(br, 3) + 3; 1935231200Smm rar_br_consume(br, 3); 1936231200Smm } else { 1937231200Smm if (!rar_br_read_ahead(a, br, 7)) { 1938231200Smm free(precode.tree); 1939231200Smm free(precode.table); 1940231200Smm goto truncated_data; 1941231200Smm } 1942231200Smm n = rar_br_bits(br, 7) + 11; 1943231200Smm rar_br_consume(br, 7); 1944231200Smm } 1945231200Smm 1946231200Smm for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) 1947231200Smm rar->lengthtable[i++] = 0; 1948231200Smm } 1949231200Smm } 1950231200Smm free(precode.tree); 1951231200Smm free(precode.table); 1952231200Smm 1953231200Smm r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE, 1954231200Smm MAX_SYMBOL_LENGTH); 1955231200Smm if (r != ARCHIVE_OK) 1956231200Smm return (r); 1957231200Smm r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE], 1958231200Smm OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); 1959231200Smm if (r != ARCHIVE_OK) 1960231200Smm return (r); 1961231200Smm r = create_code(a, &rar->lowoffsetcode, 1962231200Smm &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE], 1963231200Smm LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); 1964231200Smm if (r != ARCHIVE_OK) 1965231200Smm return (r); 1966231200Smm r = create_code(a, &rar->lengthcode, 1967231200Smm &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE + 1968231200Smm LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH); 1969231200Smm if (r != ARCHIVE_OK) 1970231200Smm return (r); 1971231200Smm } 1972231200Smm 1973231200Smm if (!rar->dictionary_size || !rar->lzss.window) 1974231200Smm { 1975231200Smm /* Seems as though dictionary sizes are not used. Even so, minimize 1976231200Smm * memory usage as much as possible. 1977231200Smm */ 1978231200Smm if (rar->unp_size >= DICTIONARY_MAX_SIZE) 1979231200Smm rar->dictionary_size = DICTIONARY_MAX_SIZE; 1980231200Smm else 1981231200Smm rar->dictionary_size = rar_fls(rar->unp_size) << 1; 1982231200Smm rar->lzss.window = (unsigned char *)realloc(rar->lzss.window, 1983231200Smm rar->dictionary_size); 1984231200Smm if (rar->lzss.window == NULL) { 1985231200Smm archive_set_error(&a->archive, ENOMEM, 1986231200Smm "Unable to allocate memory for uncompressed data."); 1987231200Smm return (ARCHIVE_FATAL); 1988231200Smm } 1989231200Smm memset(rar->lzss.window, 0, rar->dictionary_size); 1990231200Smm rar->lzss.mask = rar->dictionary_size - 1; 1991231200Smm } 1992231200Smm 1993231200Smm rar->start_new_table = 0; 1994231200Smm return (ARCHIVE_OK); 1995231200Smmtruncated_data: 1996231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1997231200Smm "Truncated RAR file data"); 1998231200Smm rar->valid = 0; 1999231200Smm return (ARCHIVE_FATAL); 2000231200Smm} 2001231200Smm 2002231200Smmstatic void 2003231200Smmfree_codes(struct archive_read *a) 2004231200Smm{ 2005231200Smm struct rar *rar = (struct rar *)(a->format->data); 2006231200Smm free(rar->maincode.tree); 2007231200Smm free(rar->offsetcode.tree); 2008231200Smm free(rar->lowoffsetcode.tree); 2009231200Smm free(rar->lengthcode.tree); 2010231200Smm free(rar->maincode.table); 2011231200Smm free(rar->offsetcode.table); 2012231200Smm free(rar->lowoffsetcode.table); 2013231200Smm free(rar->lengthcode.table); 2014231200Smm memset(&rar->maincode, 0, sizeof(rar->maincode)); 2015231200Smm memset(&rar->offsetcode, 0, sizeof(rar->offsetcode)); 2016231200Smm memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode)); 2017231200Smm memset(&rar->lengthcode, 0, sizeof(rar->lengthcode)); 2018231200Smm} 2019231200Smm 2020231200Smm 2021231200Smmstatic int 2022231200Smmread_next_symbol(struct archive_read *a, struct huffman_code *code) 2023231200Smm{ 2024231200Smm unsigned char bit; 2025231200Smm unsigned int bits; 2026231200Smm int length, value, node; 2027231200Smm struct rar *rar; 2028231200Smm struct rar_br *br; 2029231200Smm 2030231200Smm if (!code->table) 2031231200Smm { 2032231200Smm if (make_table(a, code) != (ARCHIVE_OK)) 2033231200Smm return -1; 2034231200Smm } 2035231200Smm 2036231200Smm rar = (struct rar *)(a->format->data); 2037231200Smm br = &(rar->br); 2038231200Smm 2039231200Smm /* Look ahead (peek) at bits */ 2040231200Smm if (!rar_br_read_ahead(a, br, code->tablesize)) { 2041231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2042231200Smm "Truncated RAR file data"); 2043231200Smm rar->valid = 0; 2044231200Smm return -1; 2045231200Smm } 2046231200Smm bits = rar_br_bits(br, code->tablesize); 2047231200Smm 2048231200Smm length = code->table[bits].length; 2049231200Smm value = code->table[bits].value; 2050231200Smm 2051231200Smm if (length < 0) 2052231200Smm { 2053231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2054231200Smm "Invalid prefix code in bitstream"); 2055231200Smm return -1; 2056231200Smm } 2057231200Smm 2058231200Smm if (length <= code->tablesize) 2059231200Smm { 2060231200Smm /* Skip length bits */ 2061231200Smm rar_br_consume(br, length); 2062231200Smm return value; 2063231200Smm } 2064231200Smm 2065231200Smm /* Skip tablesize bits */ 2066231200Smm rar_br_consume(br, code->tablesize); 2067231200Smm 2068231200Smm node = value; 2069231200Smm while (!(code->tree[node].branches[0] == 2070231200Smm code->tree[node].branches[1])) 2071231200Smm { 2072231200Smm if (!rar_br_read_ahead(a, br, 1)) { 2073231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2074231200Smm "Truncated RAR file data"); 2075231200Smm rar->valid = 0; 2076231200Smm return -1; 2077231200Smm } 2078231200Smm bit = rar_br_bits(br, 1); 2079231200Smm rar_br_consume(br, 1); 2080231200Smm 2081231200Smm if (code->tree[node].branches[bit] < 0) 2082231200Smm { 2083231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2084231200Smm "Invalid prefix code in bitstream"); 2085231200Smm return -1; 2086231200Smm } 2087231200Smm node = code->tree[node].branches[bit]; 2088231200Smm } 2089231200Smm 2090231200Smm return code->tree[node].branches[0]; 2091231200Smm} 2092231200Smm 2093231200Smmstatic int 2094231200Smmcreate_code(struct archive_read *a, struct huffman_code *code, 2095231200Smm unsigned char *lengths, int numsymbols, char maxlength) 2096231200Smm{ 2097231200Smm int i, j, codebits = 0, symbolsleft = numsymbols; 2098231200Smm 2099231200Smm if (new_node(code) < 0) { 2100231200Smm archive_set_error(&a->archive, ENOMEM, 2101231200Smm "Unable to allocate memory for node data."); 2102231200Smm return (ARCHIVE_FATAL); 2103231200Smm } 2104231200Smm code->numentries = 1; 2105231200Smm code->minlength = INT_MAX; 2106231200Smm code->maxlength = INT_MIN; 2107231200Smm codebits = 0; 2108231200Smm for(i = 1; i <= maxlength; i++) 2109231200Smm { 2110231200Smm for(j = 0; j < numsymbols; j++) 2111231200Smm { 2112231200Smm if (lengths[j] != i) continue; 2113231200Smm if (add_value(a, code, j, codebits, i) != ARCHIVE_OK) 2114231200Smm return (ARCHIVE_FATAL); 2115231200Smm codebits++; 2116231200Smm if (--symbolsleft <= 0) { break; break; } 2117231200Smm } 2118231200Smm codebits <<= 1; 2119231200Smm } 2120231200Smm return (ARCHIVE_OK); 2121231200Smm} 2122231200Smm 2123231200Smmstatic int 2124231200Smmadd_value(struct archive_read *a, struct huffman_code *code, int value, 2125231200Smm int codebits, int length) 2126231200Smm{ 2127231200Smm int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode; 2128231200Smm 2129231200Smm free(code->table); 2130231200Smm code->table = NULL; 2131231200Smm 2132231200Smm if(length > code->maxlength) 2133231200Smm code->maxlength = length; 2134231200Smm if(length < code->minlength) 2135231200Smm code->minlength = length; 2136231200Smm 2137231200Smm repeatpos = -1; 2138231200Smm if (repeatpos == 0 || (repeatpos >= 0 2139231200Smm && (((codebits >> (repeatpos - 1)) & 3) == 0 2140231200Smm || ((codebits >> (repeatpos - 1)) & 3) == 3))) 2141231200Smm { 2142231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2143231200Smm "Invalid repeat position"); 2144231200Smm return (ARCHIVE_FATAL); 2145231200Smm } 2146231200Smm 2147231200Smm lastnode = 0; 2148231200Smm for (bitpos = length - 1; bitpos >= 0; bitpos--) 2149231200Smm { 2150231200Smm bit = (codebits >> bitpos) & 1; 2151231200Smm 2152231200Smm /* Leaf node check */ 2153231200Smm if (code->tree[lastnode].branches[0] == 2154231200Smm code->tree[lastnode].branches[1]) 2155231200Smm { 2156231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2157231200Smm "Prefix found"); 2158231200Smm return (ARCHIVE_FATAL); 2159231200Smm } 2160231200Smm 2161231200Smm if (bitpos == repeatpos) 2162231200Smm { 2163231200Smm /* Open branch check */ 2164231200Smm if (!(code->tree[lastnode].branches[bit] < 0)) 2165231200Smm { 2166231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2167231200Smm "Invalid repeating code"); 2168231200Smm return (ARCHIVE_FATAL); 2169231200Smm } 2170231200Smm 2171231200Smm if ((repeatnode = new_node(code)) < 0) { 2172231200Smm archive_set_error(&a->archive, ENOMEM, 2173231200Smm "Unable to allocate memory for node data."); 2174231200Smm return (ARCHIVE_FATAL); 2175231200Smm } 2176231200Smm if ((nextnode = new_node(code)) < 0) { 2177231200Smm archive_set_error(&a->archive, ENOMEM, 2178231200Smm "Unable to allocate memory for node data."); 2179231200Smm return (ARCHIVE_FATAL); 2180231200Smm } 2181231200Smm 2182231200Smm /* Set branches */ 2183231200Smm code->tree[lastnode].branches[bit] = repeatnode; 2184231200Smm code->tree[repeatnode].branches[bit] = repeatnode; 2185231200Smm code->tree[repeatnode].branches[bit^1] = nextnode; 2186231200Smm lastnode = nextnode; 2187231200Smm 2188231200Smm bitpos++; /* terminating bit already handled, skip it */ 2189231200Smm } 2190231200Smm else 2191231200Smm { 2192231200Smm /* Open branch check */ 2193231200Smm if (code->tree[lastnode].branches[bit] < 0) 2194231200Smm { 2195231200Smm if (new_node(code) < 0) { 2196231200Smm archive_set_error(&a->archive, ENOMEM, 2197231200Smm "Unable to allocate memory for node data."); 2198231200Smm return (ARCHIVE_FATAL); 2199231200Smm } 2200231200Smm code->tree[lastnode].branches[bit] = code->numentries++; 2201231200Smm } 2202231200Smm 2203231200Smm /* set to branch */ 2204231200Smm lastnode = code->tree[lastnode].branches[bit]; 2205231200Smm } 2206231200Smm } 2207231200Smm 2208231200Smm if (!(code->tree[lastnode].branches[0] == -1 2209231200Smm && code->tree[lastnode].branches[1] == -2)) 2210231200Smm { 2211231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2212231200Smm "Prefix found"); 2213231200Smm return (ARCHIVE_FATAL); 2214231200Smm } 2215231200Smm 2216231200Smm /* Set leaf value */ 2217231200Smm code->tree[lastnode].branches[0] = value; 2218231200Smm code->tree[lastnode].branches[1] = value; 2219231200Smm 2220231200Smm return (ARCHIVE_OK); 2221231200Smm} 2222231200Smm 2223231200Smmstatic int 2224231200Smmnew_node(struct huffman_code *code) 2225231200Smm{ 2226231200Smm code->tree = (struct huffman_tree_node *)realloc(code->tree, 2227231200Smm (code->numentries + 1) * sizeof(*code->tree)); 2228231200Smm if (code->tree == NULL) 2229231200Smm return (-1); 2230231200Smm code->tree[code->numentries].branches[0] = -1; 2231231200Smm code->tree[code->numentries].branches[1] = -2; 2232231200Smm return 1; 2233231200Smm} 2234231200Smm 2235231200Smmstatic int 2236231200Smmmake_table(struct archive_read *a, struct huffman_code *code) 2237231200Smm{ 2238231200Smm if (code->maxlength < code->minlength || code->maxlength > 10) 2239231200Smm code->tablesize = 10; 2240231200Smm else 2241231200Smm code->tablesize = code->maxlength; 2242231200Smm 2243231200Smm code->table = 2244231200Smm (struct huffman_table_entry *)malloc(sizeof(*code->table) 2245231200Smm * (1 << code->tablesize)); 2246231200Smm 2247231200Smm return make_table_recurse(a, code, 0, code->table, 0, code->tablesize); 2248231200Smm} 2249231200Smm 2250231200Smmstatic int 2251231200Smmmake_table_recurse(struct archive_read *a, struct huffman_code *code, int node, 2252231200Smm struct huffman_table_entry *table, int depth, 2253231200Smm int maxdepth) 2254231200Smm{ 2255231200Smm int currtablesize, i, ret = (ARCHIVE_OK); 2256231200Smm 2257231200Smm if (!code->tree) 2258231200Smm { 2259231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2260231200Smm "Huffman tree was not created."); 2261231200Smm return (ARCHIVE_FATAL); 2262231200Smm } 2263231200Smm if (node < 0 || node >= code->numentries) 2264231200Smm { 2265231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2266231200Smm "Invalid location to Huffman tree specified."); 2267231200Smm return (ARCHIVE_FATAL); 2268231200Smm } 2269231200Smm 2270231200Smm currtablesize = 1 << (maxdepth - depth); 2271231200Smm 2272231200Smm if (code->tree[node].branches[0] == 2273231200Smm code->tree[node].branches[1]) 2274231200Smm { 2275231200Smm for(i = 0; i < currtablesize; i++) 2276231200Smm { 2277231200Smm table[i].length = depth; 2278231200Smm table[i].value = code->tree[node].branches[0]; 2279231200Smm } 2280231200Smm } 2281231200Smm else if (node < 0) 2282231200Smm { 2283231200Smm for(i = 0; i < currtablesize; i++) 2284231200Smm table[i].length = -1; 2285231200Smm } 2286231200Smm else 2287231200Smm { 2288231200Smm if(depth == maxdepth) 2289231200Smm { 2290231200Smm table[0].length = maxdepth + 1; 2291231200Smm table[0].value = node; 2292231200Smm } 2293231200Smm else 2294231200Smm { 2295231200Smm ret |= make_table_recurse(a, code, code->tree[node].branches[0], table, 2296231200Smm depth + 1, maxdepth); 2297231200Smm ret |= make_table_recurse(a, code, code->tree[node].branches[1], 2298231200Smm table + currtablesize / 2, depth + 1, maxdepth); 2299231200Smm } 2300231200Smm } 2301231200Smm return ret; 2302231200Smm} 2303231200Smm 2304231200Smmstatic int64_t 2305231200Smmexpand(struct archive_read *a, int64_t end) 2306231200Smm{ 2307231200Smm static const unsigned char lengthbases[] = 2308231200Smm { 0, 1, 2, 3, 4, 5, 6, 2309231200Smm 7, 8, 10, 12, 14, 16, 20, 2310231200Smm 24, 28, 32, 40, 48, 56, 64, 2311231200Smm 80, 96, 112, 128, 160, 192, 224 }; 2312231200Smm static const unsigned char lengthbits[] = 2313231200Smm { 0, 0, 0, 0, 0, 0, 0, 2314231200Smm 0, 1, 1, 1, 1, 2, 2, 2315231200Smm 2, 2, 3, 3, 3, 3, 4, 2316231200Smm 4, 4, 4, 5, 5, 5, 5 }; 2317231200Smm static const unsigned int offsetbases[] = 2318231200Smm { 0, 1, 2, 3, 4, 6, 2319231200Smm 8, 12, 16, 24, 32, 48, 2320231200Smm 64, 96, 128, 192, 256, 384, 2321231200Smm 512, 768, 1024, 1536, 2048, 3072, 2322231200Smm 4096, 6144, 8192, 12288, 16384, 24576, 2323231200Smm 32768, 49152, 65536, 98304, 131072, 196608, 2324231200Smm 262144, 327680, 393216, 458752, 524288, 589824, 2325231200Smm 655360, 720896, 786432, 851968, 917504, 983040, 2326231200Smm 1048576, 1310720, 1572864, 1835008, 2097152, 2359296, 2327231200Smm 2621440, 2883584, 3145728, 3407872, 3670016, 3932160 }; 2328231200Smm static const unsigned char offsetbits[] = 2329231200Smm { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 2330231200Smm 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 2331231200Smm 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 2332231200Smm 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2333231200Smm 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; 2334231200Smm static const unsigned char shortbases[] = 2335231200Smm { 0, 4, 8, 16, 32, 64, 128, 192 }; 2336231200Smm static const unsigned char shortbits[] = 2337231200Smm { 2, 2, 3, 4, 5, 6, 6, 6 }; 2338231200Smm 2339231200Smm int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol; 2340231200Smm unsigned char newfile; 2341231200Smm struct rar *rar = (struct rar *)(a->format->data); 2342231200Smm struct rar_br *br = &(rar->br); 2343231200Smm 2344231200Smm if (rar->filterstart < end) 2345231200Smm end = rar->filterstart; 2346231200Smm 2347231200Smm while (1) 2348231200Smm { 2349231200Smm if (rar->output_last_match && 2350231200Smm lzss_position(&rar->lzss) + rar->lastlength <= end) 2351231200Smm { 2352231200Smm lzss_emit_match(rar, rar->lastoffset, rar->lastlength); 2353231200Smm rar->output_last_match = 0; 2354231200Smm } 2355231200Smm 2356231200Smm if(rar->is_ppmd_block || rar->output_last_match || 2357231200Smm lzss_position(&rar->lzss) >= end) 2358231200Smm return lzss_position(&rar->lzss); 2359231200Smm 2360231200Smm if ((symbol = read_next_symbol(a, &rar->maincode)) < 0) 2361231200Smm return (ARCHIVE_FATAL); 2362231200Smm rar->output_last_match = 0; 2363231200Smm 2364231200Smm if (symbol < 256) 2365231200Smm { 2366231200Smm lzss_emit_literal(rar, symbol); 2367231200Smm continue; 2368231200Smm } 2369231200Smm else if (symbol == 256) 2370231200Smm { 2371231200Smm if (!rar_br_read_ahead(a, br, 1)) 2372231200Smm goto truncated_data; 2373231200Smm newfile = !rar_br_bits(br, 1); 2374231200Smm rar_br_consume(br, 1); 2375231200Smm 2376231200Smm if(newfile) 2377231200Smm { 2378231200Smm rar->start_new_block = 1; 2379231200Smm if (!rar_br_read_ahead(a, br, 1)) 2380231200Smm goto truncated_data; 2381231200Smm rar->start_new_table = rar_br_bits(br, 1); 2382231200Smm rar_br_consume(br, 1); 2383231200Smm return lzss_position(&rar->lzss); 2384231200Smm } 2385231200Smm else 2386231200Smm { 2387231200Smm if (parse_codes(a) != ARCHIVE_OK) 2388231200Smm return (ARCHIVE_FATAL); 2389231200Smm continue; 2390231200Smm } 2391231200Smm } 2392231200Smm else if(symbol==257) 2393231200Smm { 2394231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 2395231200Smm "Parsing filters is unsupported."); 2396231200Smm return (ARCHIVE_FAILED); 2397231200Smm } 2398231200Smm else if(symbol==258) 2399231200Smm { 2400231200Smm if(rar->lastlength == 0) 2401231200Smm continue; 2402231200Smm 2403231200Smm offs = rar->lastoffset; 2404231200Smm len = rar->lastlength; 2405231200Smm } 2406231200Smm else if (symbol <= 262) 2407231200Smm { 2408231200Smm offsindex = symbol - 259; 2409231200Smm offs = rar->oldoffset[offsindex]; 2410231200Smm 2411231200Smm if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0) 2412231200Smm goto bad_data; 2413232153Smm if (lensymbol > (int)(sizeof(lengthbases)/sizeof(lengthbases[0]))) 2414231200Smm goto bad_data; 2415232153Smm if (lensymbol > (int)(sizeof(lengthbits)/sizeof(lengthbits[0]))) 2416231200Smm goto bad_data; 2417231200Smm len = lengthbases[lensymbol] + 2; 2418231200Smm if (lengthbits[lensymbol] > 0) { 2419231200Smm if (!rar_br_read_ahead(a, br, lengthbits[lensymbol])) 2420231200Smm goto truncated_data; 2421231200Smm len += rar_br_bits(br, lengthbits[lensymbol]); 2422231200Smm rar_br_consume(br, lengthbits[lensymbol]); 2423231200Smm } 2424231200Smm 2425231200Smm for (i = offsindex; i > 0; i--) 2426231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2427231200Smm rar->oldoffset[0] = offs; 2428231200Smm } 2429231200Smm else if(symbol<=270) 2430231200Smm { 2431231200Smm offs = shortbases[symbol-263] + 1; 2432231200Smm if(shortbits[symbol-263] > 0) { 2433231200Smm if (!rar_br_read_ahead(a, br, shortbits[symbol-263])) 2434231200Smm goto truncated_data; 2435231200Smm offs += rar_br_bits(br, shortbits[symbol-263]); 2436231200Smm rar_br_consume(br, shortbits[symbol-263]); 2437231200Smm } 2438231200Smm 2439231200Smm len = 2; 2440231200Smm 2441231200Smm for(i = 3; i > 0; i--) 2442231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2443231200Smm rar->oldoffset[0] = offs; 2444231200Smm } 2445231200Smm else 2446231200Smm { 2447232153Smm if (symbol-271 > (int)(sizeof(lengthbases)/sizeof(lengthbases[0]))) 2448231200Smm goto bad_data; 2449232153Smm if (symbol-271 > (int)(sizeof(lengthbits)/sizeof(lengthbits[0]))) 2450231200Smm goto bad_data; 2451231200Smm len = lengthbases[symbol-271]+3; 2452231200Smm if(lengthbits[symbol-271] > 0) { 2453231200Smm if (!rar_br_read_ahead(a, br, lengthbits[symbol-271])) 2454231200Smm goto truncated_data; 2455231200Smm len += rar_br_bits(br, lengthbits[symbol-271]); 2456231200Smm rar_br_consume(br, lengthbits[symbol-271]); 2457231200Smm } 2458231200Smm 2459231200Smm if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0) 2460231200Smm goto bad_data; 2461232153Smm if (offssymbol > (int)(sizeof(offsetbases)/sizeof(offsetbases[0]))) 2462231200Smm goto bad_data; 2463232153Smm if (offssymbol > (int)(sizeof(offsetbits)/sizeof(offsetbits[0]))) 2464231200Smm goto bad_data; 2465231200Smm offs = offsetbases[offssymbol]+1; 2466231200Smm if(offsetbits[offssymbol] > 0) 2467231200Smm { 2468231200Smm if(offssymbol > 9) 2469231200Smm { 2470231200Smm if(offsetbits[offssymbol] > 4) { 2471231200Smm if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4)) 2472231200Smm goto truncated_data; 2473231200Smm offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4; 2474231200Smm rar_br_consume(br, offsetbits[offssymbol] - 4); 2475231200Smm } 2476231200Smm 2477231200Smm if(rar->numlowoffsetrepeats > 0) 2478231200Smm { 2479231200Smm rar->numlowoffsetrepeats--; 2480231200Smm offs += rar->lastlowoffset; 2481231200Smm } 2482231200Smm else 2483231200Smm { 2484231200Smm if ((lowoffsetsymbol = 2485231200Smm read_next_symbol(a, &rar->lowoffsetcode)) < 0) 2486231200Smm return (ARCHIVE_FATAL); 2487231200Smm if(lowoffsetsymbol == 16) 2488231200Smm { 2489231200Smm rar->numlowoffsetrepeats = 15; 2490231200Smm offs += rar->lastlowoffset; 2491231200Smm } 2492231200Smm else 2493231200Smm { 2494231200Smm offs += lowoffsetsymbol; 2495231200Smm rar->lastlowoffset = lowoffsetsymbol; 2496231200Smm } 2497231200Smm } 2498231200Smm } 2499231200Smm else { 2500231200Smm if (!rar_br_read_ahead(a, br, offsetbits[offssymbol])) 2501231200Smm goto truncated_data; 2502231200Smm offs += rar_br_bits(br, offsetbits[offssymbol]); 2503231200Smm rar_br_consume(br, offsetbits[offssymbol]); 2504231200Smm } 2505231200Smm } 2506231200Smm 2507231200Smm if (offs >= 0x40000) 2508231200Smm len++; 2509231200Smm if (offs >= 0x2000) 2510231200Smm len++; 2511231200Smm 2512231200Smm for(i = 3; i > 0; i--) 2513231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2514231200Smm rar->oldoffset[0] = offs; 2515231200Smm } 2516231200Smm 2517231200Smm rar->lastoffset = offs; 2518231200Smm rar->lastlength = len; 2519231200Smm rar->output_last_match = 1; 2520231200Smm } 2521231200Smmtruncated_data: 2522231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2523231200Smm "Truncated RAR file data"); 2524231200Smm rar->valid = 0; 2525231200Smm return (ARCHIVE_FATAL); 2526231200Smmbad_data: 2527231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2528231200Smm "Bad RAR file data"); 2529231200Smm return (ARCHIVE_FATAL); 2530231200Smm} 2531231200Smm 2532231200Smmstatic int 2533231200Smmcopy_from_lzss_window(struct archive_read *a, const void **buffer, 2534231200Smm int64_t startpos, int length) 2535231200Smm{ 2536231200Smm int windowoffs, firstpart; 2537231200Smm struct rar *rar = (struct rar *)(a->format->data); 2538231200Smm 2539231200Smm if (!rar->unp_buffer) 2540231200Smm { 2541231200Smm if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL) 2542231200Smm { 2543231200Smm archive_set_error(&a->archive, ENOMEM, 2544231200Smm "Unable to allocate memory for uncompressed data."); 2545231200Smm return (ARCHIVE_FATAL); 2546231200Smm } 2547231200Smm } 2548231200Smm 2549231200Smm windowoffs = lzss_offset_for_position(&rar->lzss, startpos); 2550231200Smm if(windowoffs + length <= lzss_size(&rar->lzss)) 2551231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs], 2552231200Smm length); 2553231200Smm else 2554231200Smm { 2555231200Smm firstpart = lzss_size(&rar->lzss) - windowoffs; 2556231200Smm if (firstpart < 0) { 2557231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2558231200Smm "Bad RAR file data"); 2559231200Smm return (ARCHIVE_FATAL); 2560231200Smm } 2561231200Smm if (firstpart < length) { 2562231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], 2563231200Smm &rar->lzss.window[windowoffs], firstpart); 2564231200Smm memcpy(&rar->unp_buffer[rar->unp_offset + firstpart], 2565231200Smm &rar->lzss.window[0], length - firstpart); 2566231200Smm } else 2567231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], 2568231200Smm &rar->lzss.window[windowoffs], length); 2569231200Smm } 2570231200Smm rar->unp_offset += length; 2571231200Smm if (rar->unp_offset >= rar->unp_buffer_size) 2572231200Smm *buffer = rar->unp_buffer; 2573231200Smm else 2574231200Smm *buffer = NULL; 2575231200Smm return (ARCHIVE_OK); 2576231200Smm} 2577