archive_read_support_format_rar.c revision 231200
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); 308231200Smmstatic time_t get_time(int time); 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 } 760231200Smm } else 761231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 762231200Smm "rar: unknown keyword ``%s''", key); 763231200Smm 764231200Smm return (ret); 765231200Smm} 766231200Smm 767231200Smmstatic int 768231200Smmarchive_read_format_rar_read_header(struct archive_read *a, 769231200Smm struct archive_entry *entry) 770231200Smm{ 771231200Smm const void *h; 772231200Smm const char *p; 773231200Smm struct rar *rar; 774231200Smm size_t skip; 775231200Smm char head_type; 776231200Smm int ret; 777231200Smm unsigned flags; 778231200Smm 779231200Smm a->archive.archive_format = ARCHIVE_FORMAT_RAR; 780231200Smm if (a->archive.archive_format_name == NULL) 781231200Smm a->archive.archive_format_name = "RAR"; 782231200Smm 783231200Smm rar = (struct rar *)(a->format->data); 784231200Smm 785231200Smm /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if 786231200Smm * this fails. 787231200Smm */ 788231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 789231200Smm return (ARCHIVE_EOF); 790231200Smm 791231200Smm p = h; 792231200Smm if (rar->found_first_header == 0 && 793231200Smm ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) { 794231200Smm /* This is an executable ? Must be self-extracting... */ 795231200Smm ret = skip_sfx(a); 796231200Smm if (ret < ARCHIVE_WARN) 797231200Smm return (ret); 798231200Smm } 799231200Smm rar->found_first_header = 1; 800231200Smm 801231200Smm while (1) 802231200Smm { 803231200Smm unsigned long crc32_val; 804231200Smm 805231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 806231200Smm return (ARCHIVE_FATAL); 807231200Smm p = h; 808231200Smm 809231200Smm head_type = p[2]; 810231200Smm switch(head_type) 811231200Smm { 812231200Smm case MARK_HEAD: 813231200Smm if (memcmp(p, RAR_SIGNATURE, 7) != 0) { 814231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 815231200Smm "Invalid marker header"); 816231200Smm return (ARCHIVE_FATAL); 817231200Smm } 818231200Smm __archive_read_consume(a, 7); 819231200Smm break; 820231200Smm 821231200Smm case MAIN_HEAD: 822231200Smm rar->main_flags = archive_le16dec(p + 3); 823231200Smm skip = archive_le16dec(p + 5); 824231200Smm if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) { 825231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 826231200Smm "Invalid header size"); 827231200Smm return (ARCHIVE_FATAL); 828231200Smm } 829231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 830231200Smm return (ARCHIVE_FATAL); 831231200Smm p = h; 832231200Smm memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1)); 833231200Smm memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1), 834231200Smm sizeof(rar->reserved2)); 835231200Smm if (rar->main_flags & MHD_ENCRYPTVER) { 836231200Smm if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) { 837231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 838231200Smm "Invalid header size"); 839231200Smm return (ARCHIVE_FATAL); 840231200Smm } 841231200Smm rar->encryptver = *(p + 7 + sizeof(rar->reserved1) + 842231200Smm sizeof(rar->reserved2)); 843231200Smm } 844231200Smm 845231200Smm if (rar->main_flags & MHD_VOLUME || 846231200Smm rar->main_flags & MHD_FIRSTVOLUME) 847231200Smm { 848231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 849231200Smm "RAR volume support unavailable."); 850231200Smm return (ARCHIVE_FATAL); 851231200Smm } 852231200Smm if (rar->main_flags & MHD_PASSWORD) 853231200Smm { 854231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 855231200Smm "RAR encryption support unavailable."); 856231200Smm return (ARCHIVE_FATAL); 857231200Smm } 858231200Smm 859231200Smm crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2); 860231200Smm if ((crc32_val & 0xffff) != archive_le16dec(p)) { 861231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 862231200Smm "Header CRC error"); 863231200Smm return (ARCHIVE_FATAL); 864231200Smm } 865231200Smm __archive_read_consume(a, skip); 866231200Smm break; 867231200Smm 868231200Smm case FILE_HEAD: 869231200Smm return read_header(a, entry, head_type); 870231200Smm 871231200Smm case COMM_HEAD: 872231200Smm case AV_HEAD: 873231200Smm case SUB_HEAD: 874231200Smm case PROTECT_HEAD: 875231200Smm case SIGN_HEAD: 876231200Smm flags = archive_le16dec(p + 3); 877231200Smm skip = archive_le16dec(p + 5); 878231200Smm if (skip < 7) { 879231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 880231200Smm "Invalid header size"); 881231200Smm return (ARCHIVE_FATAL); 882231200Smm } 883231200Smm if (skip > 7) { 884231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 885231200Smm return (ARCHIVE_FATAL); 886231200Smm p = h; 887231200Smm } 888231200Smm if (flags & HD_ADD_SIZE_PRESENT) 889231200Smm { 890231200Smm if (skip < 7 + 4) { 891231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 892231200Smm "Invalid header size"); 893231200Smm return (ARCHIVE_FATAL); 894231200Smm } 895231200Smm skip += archive_le32dec(p + 7); 896231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 897231200Smm return (ARCHIVE_FATAL); 898231200Smm p = h; 899231200Smm } 900231200Smm 901231200Smm crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2); 902231200Smm if ((crc32_val & 0xffff) != archive_le16dec(p)) { 903231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 904231200Smm "Header CRC error"); 905231200Smm return (ARCHIVE_FATAL); 906231200Smm } 907231200Smm __archive_read_consume(a, skip); 908231200Smm break; 909231200Smm 910231200Smm case NEWSUB_HEAD: 911231200Smm if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN) 912231200Smm return ret; 913231200Smm break; 914231200Smm 915231200Smm case ENDARC_HEAD: 916231200Smm return (ARCHIVE_EOF); 917231200Smm 918231200Smm default: 919231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 920231200Smm "Bad RAR file"); 921231200Smm return (ARCHIVE_FATAL); 922231200Smm } 923231200Smm } 924231200Smm} 925231200Smm 926231200Smmstatic int 927231200Smmarchive_read_format_rar_read_data(struct archive_read *a, const void **buff, 928231200Smm size_t *size, int64_t *offset) 929231200Smm{ 930231200Smm struct rar *rar = (struct rar *)(a->format->data); 931231200Smm int ret; 932231200Smm 933231200Smm if (rar->bytes_unconsumed > 0) { 934231200Smm /* Consume as much as the decompressor actually used. */ 935231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 936231200Smm rar->bytes_unconsumed = 0; 937231200Smm } 938231200Smm 939231200Smm if (rar->entry_eof) { 940231200Smm *buff = NULL; 941231200Smm *size = 0; 942231200Smm *offset = rar->offset; 943231200Smm return (ARCHIVE_EOF); 944231200Smm } 945231200Smm 946231200Smm switch (rar->compression_method) 947231200Smm { 948231200Smm case COMPRESS_METHOD_STORE: 949231200Smm ret = read_data_stored(a, buff, size, offset); 950231200Smm break; 951231200Smm 952231200Smm case COMPRESS_METHOD_FASTEST: 953231200Smm case COMPRESS_METHOD_FAST: 954231200Smm case COMPRESS_METHOD_NORMAL: 955231200Smm case COMPRESS_METHOD_GOOD: 956231200Smm case COMPRESS_METHOD_BEST: 957231200Smm ret = read_data_compressed(a, buff, size, offset); 958231200Smm if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) 959231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 960231200Smm break; 961231200Smm 962231200Smm default: 963231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 964231200Smm "Unsupported compression method for RAR file."); 965231200Smm ret = ARCHIVE_FATAL; 966231200Smm break; 967231200Smm } 968231200Smm return (ret); 969231200Smm} 970231200Smm 971231200Smmstatic int 972231200Smmarchive_read_format_rar_read_data_skip(struct archive_read *a) 973231200Smm{ 974231200Smm struct rar *rar; 975231200Smm int64_t bytes_skipped; 976231200Smm 977231200Smm rar = (struct rar *)(a->format->data); 978231200Smm 979231200Smm if (rar->bytes_unconsumed > 0) { 980231200Smm /* Consume as much as the decompressor actually used. */ 981231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 982231200Smm rar->bytes_unconsumed = 0; 983231200Smm } 984231200Smm 985231200Smm if (rar->bytes_remaining > 0) { 986231200Smm bytes_skipped = __archive_read_consume(a, rar->bytes_remaining); 987231200Smm if (bytes_skipped < 0) 988231200Smm return (ARCHIVE_FATAL); 989231200Smm } 990231200Smm return (ARCHIVE_OK); 991231200Smm} 992231200Smm 993231200Smmstatic int 994231200Smmarchive_read_format_rar_cleanup(struct archive_read *a) 995231200Smm{ 996231200Smm struct rar *rar; 997231200Smm 998231200Smm rar = (struct rar *)(a->format->data); 999231200Smm free_codes(a); 1000231200Smm free(rar->filename); 1001231200Smm free(rar->unp_buffer); 1002231200Smm free(rar->lzss.window); 1003231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 1004231200Smm free(rar); 1005231200Smm (a->format->data) = NULL; 1006231200Smm return (ARCHIVE_OK); 1007231200Smm} 1008231200Smm 1009231200Smmstatic int 1010231200Smmread_header(struct archive_read *a, struct archive_entry *entry, 1011231200Smm char head_type) 1012231200Smm{ 1013231200Smm const void *h; 1014231200Smm const char *p, *endp; 1015231200Smm struct rar *rar; 1016231200Smm struct rar_header rar_header; 1017231200Smm struct rar_file_header file_header; 1018231200Smm int64_t header_size; 1019231200Smm unsigned filename_size, end; 1020231200Smm char *filename; 1021231200Smm char *strp; 1022231200Smm char packed_size[8]; 1023231200Smm char unp_size[8]; 1024231200Smm int time; 1025231200Smm struct archive_string_conv *sconv, *fn_sconv; 1026231200Smm unsigned long crc32_val; 1027231200Smm int ret = (ARCHIVE_OK), ret2; 1028231200Smm 1029231200Smm rar = (struct rar *)(a->format->data); 1030231200Smm 1031231200Smm /* Setup a string conversion object for non-rar-unicode filenames. */ 1032231200Smm sconv = rar->opt_sconv; 1033231200Smm if (sconv == NULL) { 1034231200Smm if (!rar->init_default_conversion) { 1035231200Smm rar->sconv_default = 1036231200Smm archive_string_default_conversion_for_read( 1037231200Smm &(a->archive)); 1038231200Smm rar->init_default_conversion = 1; 1039231200Smm } 1040231200Smm sconv = rar->sconv_default; 1041231200Smm } 1042231200Smm 1043231200Smm 1044231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 1045231200Smm return (ARCHIVE_FATAL); 1046231200Smm p = h; 1047231200Smm memcpy(&rar_header, p, sizeof(rar_header)); 1048231200Smm rar->file_flags = archive_le16dec(rar_header.flags); 1049231200Smm header_size = archive_le16dec(rar_header.size); 1050231200Smm if (header_size < sizeof(file_header) + 7) { 1051231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1052231200Smm "Invalid header size"); 1053231200Smm return (ARCHIVE_FATAL); 1054231200Smm } 1055231200Smm crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2); 1056231200Smm __archive_read_consume(a, 7); 1057231200Smm 1058231200Smm if (!(rar->file_flags & FHD_SOLID)) 1059231200Smm { 1060231200Smm rar->compression_method = 0; 1061231200Smm rar->packed_size = 0; 1062231200Smm rar->unp_size = 0; 1063231200Smm rar->mtime = 0; 1064231200Smm rar->ctime = 0; 1065231200Smm rar->atime = 0; 1066231200Smm rar->arctime = 0; 1067231200Smm rar->mode = 0; 1068231200Smm memset(&rar->salt, 0, sizeof(rar->salt)); 1069231200Smm rar->atime = 0; 1070231200Smm rar->ansec = 0; 1071231200Smm rar->ctime = 0; 1072231200Smm rar->cnsec = 0; 1073231200Smm rar->mtime = 0; 1074231200Smm rar->mnsec = 0; 1075231200Smm rar->arctime = 0; 1076231200Smm rar->arcnsec = 0; 1077231200Smm } 1078231200Smm else 1079231200Smm { 1080231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1081231200Smm "RAR solid archive support unavailable."); 1082231200Smm return (ARCHIVE_FATAL); 1083231200Smm } 1084231200Smm 1085231200Smm if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL) 1086231200Smm return (ARCHIVE_FATAL); 1087231200Smm 1088231200Smm /* File Header CRC check. */ 1089231200Smm crc32_val = crc32(crc32_val, h, header_size - 7); 1090231200Smm if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) { 1091231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1092231200Smm "Header CRC error"); 1093231200Smm return (ARCHIVE_FATAL); 1094231200Smm } 1095231200Smm /* If no CRC error, Go on parsing File Header. */ 1096231200Smm p = h; 1097231200Smm endp = p + header_size - 7; 1098231200Smm memcpy(&file_header, p, sizeof(file_header)); 1099231200Smm p += sizeof(file_header); 1100231200Smm 1101231200Smm rar->compression_method = file_header.method; 1102231200Smm 1103231200Smm time = archive_le32dec(file_header.file_time); 1104231200Smm rar->mtime = get_time(time); 1105231200Smm 1106231200Smm rar->file_crc = archive_le32dec(file_header.file_crc); 1107231200Smm 1108231200Smm if (rar->file_flags & FHD_PASSWORD) 1109231200Smm { 1110231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1111231200Smm "RAR encryption support unavailable."); 1112231200Smm return (ARCHIVE_FATAL); 1113231200Smm } 1114231200Smm 1115231200Smm if (rar->file_flags & FHD_LARGE) 1116231200Smm { 1117231200Smm memcpy(packed_size, file_header.pack_size, 4); 1118231200Smm memcpy(packed_size + 4, p, 4); /* High pack size */ 1119231200Smm p += 4; 1120231200Smm memcpy(unp_size, file_header.unp_size, 4); 1121231200Smm memcpy(unp_size + 4, p, 4); /* High unpack size */ 1122231200Smm p += 4; 1123231200Smm rar->packed_size = archive_le64dec(&packed_size); 1124231200Smm rar->unp_size = archive_le64dec(&unp_size); 1125231200Smm } 1126231200Smm else 1127231200Smm { 1128231200Smm rar->packed_size = archive_le32dec(file_header.pack_size); 1129231200Smm rar->unp_size = archive_le32dec(file_header.unp_size); 1130231200Smm } 1131231200Smm 1132231200Smm /* TODO: Need to use CRC check for these kind of cases. 1133231200Smm * For now, check if sizes are not < 0. 1134231200Smm */ 1135231200Smm if (rar->packed_size < 0 || rar->unp_size < 0) 1136231200Smm { 1137231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1138231200Smm "Invalid sizes specified."); 1139231200Smm return (ARCHIVE_FATAL); 1140231200Smm } 1141231200Smm 1142231200Smm /* TODO: RARv3 subblocks contain comments. For now the complete block is 1143231200Smm * consumed at the end. 1144231200Smm */ 1145231200Smm if (head_type == NEWSUB_HEAD) { 1146231200Smm size_t distance = p - (const char *)h; 1147231200Smm header_size += rar->packed_size; 1148231200Smm /* Make sure we have the extended data. */ 1149231200Smm if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL) 1150231200Smm return (ARCHIVE_FATAL); 1151231200Smm p = h; 1152231200Smm endp = p + header_size - 7; 1153231200Smm p += distance; 1154231200Smm } 1155231200Smm 1156231200Smm filename_size = archive_le16dec(file_header.name_size); 1157231200Smm if (p + filename_size > endp) { 1158231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1159231200Smm "Invalid filename size"); 1160231200Smm return (ARCHIVE_FATAL); 1161231200Smm } 1162231200Smm if (rar->filename_allocated < filename_size+2) { 1163231200Smm rar->filename = realloc(rar->filename, filename_size+2); 1164231200Smm if (rar->filename == NULL) { 1165231200Smm archive_set_error(&a->archive, ENOMEM, 1166231200Smm "Couldn't allocate memory."); 1167231200Smm return (ARCHIVE_FATAL); 1168231200Smm } 1169231200Smm } 1170231200Smm filename = rar->filename; 1171231200Smm memcpy(filename, p, filename_size); 1172231200Smm filename[filename_size] = '\0'; 1173231200Smm if (rar->file_flags & FHD_UNICODE) 1174231200Smm { 1175231200Smm if (filename_size != strlen(filename)) 1176231200Smm { 1177231200Smm unsigned char highbyte, flagbits, flagbyte, length, offset; 1178231200Smm 1179231200Smm end = filename_size; 1180231200Smm filename_size = 0; 1181231200Smm offset = strlen(filename) + 1; 1182231200Smm highbyte = *(p + offset++); 1183231200Smm flagbits = 0; 1184231200Smm flagbyte = 0; 1185231200Smm while (offset < end && filename_size < end) 1186231200Smm { 1187231200Smm if (!flagbits) 1188231200Smm { 1189231200Smm flagbyte = *(p + offset++); 1190231200Smm flagbits = 8; 1191231200Smm } 1192231200Smm 1193231200Smm flagbits -= 2; 1194231200Smm switch((flagbyte >> flagbits) & 3) 1195231200Smm { 1196231200Smm case 0: 1197231200Smm filename[filename_size++] = '\0'; 1198231200Smm filename[filename_size++] = *(p + offset++); 1199231200Smm break; 1200231200Smm case 1: 1201231200Smm filename[filename_size++] = highbyte; 1202231200Smm filename[filename_size++] = *(p + offset++); 1203231200Smm break; 1204231200Smm case 2: 1205231200Smm filename[filename_size++] = *(p + offset + 1); 1206231200Smm filename[filename_size++] = *(p + offset); 1207231200Smm offset += 2; 1208231200Smm break; 1209231200Smm case 3: 1210231200Smm { 1211231200Smm length = *(p + offset++); 1212231200Smm while (length) 1213231200Smm { 1214231200Smm if (filename_size >= end) 1215231200Smm break; 1216231200Smm filename[filename_size++] = *(p + offset); 1217231200Smm length--; 1218231200Smm } 1219231200Smm } 1220231200Smm break; 1221231200Smm } 1222231200Smm } 1223231200Smm if (filename_size >= end) { 1224231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1225231200Smm "Invalid filename"); 1226231200Smm return (ARCHIVE_FATAL); 1227231200Smm } 1228231200Smm filename[filename_size++] = '\0'; 1229231200Smm filename[filename_size++] = '\0'; 1230231200Smm 1231231200Smm /* Decoded unicode form is UTF-16BE, so we have to update a string 1232231200Smm * conversion object for it. */ 1233231200Smm if (rar->sconv_utf16be == NULL) { 1234231200Smm rar->sconv_utf16be = archive_string_conversion_from_charset( 1235231200Smm &a->archive, "UTF-16BE", 1); 1236231200Smm if (rar->sconv_utf16be == NULL) 1237231200Smm return (ARCHIVE_FATAL); 1238231200Smm } 1239231200Smm fn_sconv = rar->sconv_utf16be; 1240231200Smm 1241231200Smm strp = filename; 1242231200Smm while (memcmp(strp, "\x00\x00", 2)) 1243231200Smm { 1244231200Smm if (!memcmp(strp, "\x00\\", 2)) 1245231200Smm *(strp + 1) = '/'; 1246231200Smm strp += 2; 1247231200Smm } 1248231200Smm p += offset; 1249231200Smm } else { 1250231200Smm /* 1251231200Smm * If FHD_UNICODE is set but no unicode data, this file name form 1252231200Smm * is UTF-8, so we have to update a string conversion object for 1253231200Smm * it accordingly. 1254231200Smm */ 1255231200Smm if (rar->sconv_utf8 == NULL) { 1256231200Smm rar->sconv_utf8 = archive_string_conversion_from_charset( 1257231200Smm &a->archive, "UTF-8", 1); 1258231200Smm if (rar->sconv_utf8 == NULL) 1259231200Smm return (ARCHIVE_FATAL); 1260231200Smm } 1261231200Smm fn_sconv = rar->sconv_utf8; 1262231200Smm while ((strp = strchr(filename, '\\')) != NULL) 1263231200Smm *strp = '/'; 1264231200Smm p += filename_size; 1265231200Smm } 1266231200Smm } 1267231200Smm else 1268231200Smm { 1269231200Smm fn_sconv = sconv; 1270231200Smm while ((strp = strchr(filename, '\\')) != NULL) 1271231200Smm *strp = '/'; 1272231200Smm p += filename_size; 1273231200Smm } 1274231200Smm 1275231200Smm if (rar->file_flags & FHD_SALT) 1276231200Smm { 1277231200Smm if (p + 8 > endp) { 1278231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1279231200Smm "Invalid header size"); 1280231200Smm return (ARCHIVE_FATAL); 1281231200Smm } 1282231200Smm memcpy(rar->salt, p, 8); 1283231200Smm p += 8; 1284231200Smm } 1285231200Smm 1286231200Smm if (rar->file_flags & FHD_EXTTIME) { 1287231200Smm if (read_exttime(p, rar, endp) < 0) { 1288231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1289231200Smm "Invalid header size"); 1290231200Smm return (ARCHIVE_FATAL); 1291231200Smm } 1292231200Smm } 1293231200Smm 1294231200Smm __archive_read_consume(a, header_size - 7); 1295231200Smm 1296231200Smm switch(file_header.host_os) 1297231200Smm { 1298231200Smm case OS_MSDOS: 1299231200Smm case OS_OS2: 1300231200Smm case OS_WIN32: 1301231200Smm rar->mode = archive_le32dec(file_header.file_attr); 1302231200Smm if (rar->mode & FILE_ATTRIBUTE_DIRECTORY) 1303231200Smm rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; 1304231200Smm else 1305231200Smm rar->mode = AE_IFREG; 1306231200Smm rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 1307231200Smm break; 1308231200Smm 1309231200Smm case OS_UNIX: 1310231200Smm case OS_MAC_OS: 1311231200Smm case OS_BEOS: 1312231200Smm rar->mode = archive_le32dec(file_header.file_attr); 1313231200Smm break; 1314231200Smm 1315231200Smm default: 1316231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1317231200Smm "Unknown file attributes from RAR file's host OS"); 1318231200Smm return (ARCHIVE_FATAL); 1319231200Smm } 1320231200Smm 1321231200Smm rar->bytes_remaining = rar->packed_size; 1322231200Smm rar->bytes_uncopied = rar->bytes_unconsumed = 0; 1323231200Smm rar->lzss.position = rar->dictionary_size = rar->offset = 0; 1324231200Smm rar->offset_outgoing = 0; 1325231200Smm rar->br.cache_avail = 0; 1326231200Smm rar->br.avail_in = 0; 1327231200Smm rar->crc_calculated = 0; 1328231200Smm rar->entry_eof = 0; 1329231200Smm rar->valid = 1; 1330231200Smm rar->is_ppmd_block = 0; 1331231200Smm rar->start_new_table = 1; 1332231200Smm free(rar->unp_buffer); 1333231200Smm rar->unp_buffer = NULL; 1334231200Smm rar->unp_offset = 0; 1335231200Smm rar->unp_buffer_size = UNP_BUFFER_SIZE; 1336231200Smm memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); 1337231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 1338231200Smm rar->ppmd_valid = rar->ppmd_eod = 0; 1339231200Smm 1340231200Smm /* Don't set any archive entries for non-file header types */ 1341231200Smm if (head_type == NEWSUB_HEAD) 1342231200Smm return ret; 1343231200Smm 1344231200Smm archive_entry_set_mtime(entry, rar->mtime, rar->mnsec); 1345231200Smm archive_entry_set_ctime(entry, rar->ctime, rar->cnsec); 1346231200Smm archive_entry_set_atime(entry, rar->atime, rar->ansec); 1347231200Smm archive_entry_set_size(entry, rar->unp_size); 1348231200Smm archive_entry_set_mode(entry, rar->mode); 1349231200Smm 1350231200Smm if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv)) 1351231200Smm { 1352231200Smm if (errno == ENOMEM) 1353231200Smm { 1354231200Smm archive_set_error(&a->archive, ENOMEM, 1355231200Smm "Can't allocate memory for Pathname"); 1356231200Smm return (ARCHIVE_FATAL); 1357231200Smm } 1358231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1359231200Smm "Pathname cannot be converted from %s to current locale.", 1360231200Smm archive_string_conversion_charset_name(fn_sconv)); 1361231200Smm ret = (ARCHIVE_WARN); 1362231200Smm } 1363231200Smm 1364231200Smm if (((rar->mode) & AE_IFMT) == AE_IFLNK) 1365231200Smm { 1366231200Smm /* Make sure a symbolic-link file does not have its body. */ 1367231200Smm rar->bytes_remaining = 0; 1368231200Smm archive_entry_set_size(entry, 0); 1369231200Smm 1370231200Smm /* Read a symbolic-link name. */ 1371231200Smm if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN)) 1372231200Smm return ret2; 1373231200Smm if (ret > ret2) 1374231200Smm ret = ret2; 1375231200Smm } 1376231200Smm 1377231200Smm if (rar->bytes_remaining == 0) 1378231200Smm rar->entry_eof = 1; 1379231200Smm 1380231200Smm return ret; 1381231200Smm} 1382231200Smm 1383231200Smmstatic time_t 1384231200Smmget_time(int time) 1385231200Smm{ 1386231200Smm struct tm tm; 1387231200Smm tm.tm_sec = 2 * (time & 0x1f); 1388231200Smm tm.tm_min = (time >> 5) & 0x3f; 1389231200Smm tm.tm_hour = (time >> 11) & 0x1f; 1390231200Smm tm.tm_mday = (time >> 16) & 0x1f; 1391231200Smm tm.tm_mon = ((time >> 21) & 0x0f) - 1; 1392231200Smm tm.tm_year = ((time >> 25) & 0x7f) + 80; 1393231200Smm tm.tm_isdst = -1; 1394231200Smm return mktime(&tm); 1395231200Smm} 1396231200Smm 1397231200Smmstatic int 1398231200Smmread_exttime(const char *p, struct rar *rar, const char *endp) 1399231200Smm{ 1400231200Smm unsigned rmode, flags, rem, j, count; 1401231200Smm int time, i; 1402231200Smm struct tm *tm; 1403231200Smm time_t t; 1404231200Smm long nsec; 1405231200Smm 1406231200Smm if (p + 2 > endp) 1407231200Smm return (-1); 1408231200Smm flags = archive_le16dec(p); 1409231200Smm p += 2; 1410231200Smm 1411231200Smm for (i = 3; i >= 0; i--) 1412231200Smm { 1413231200Smm t = 0; 1414231200Smm if (i == 3) 1415231200Smm t = rar->mtime; 1416231200Smm rmode = flags >> i * 4; 1417231200Smm if (rmode & 8) 1418231200Smm { 1419231200Smm if (!t) 1420231200Smm { 1421231200Smm if (p + 4 > endp) 1422231200Smm return (-1); 1423231200Smm time = archive_le32dec(p); 1424231200Smm t = get_time(time); 1425231200Smm p += 4; 1426231200Smm } 1427231200Smm rem = 0; 1428231200Smm count = rmode & 3; 1429231200Smm if (p + count > endp) 1430231200Smm return (-1); 1431231200Smm for (j = 0; j < count; j++) 1432231200Smm { 1433231200Smm rem = ((*p) << 16) | (rem >> 8); 1434231200Smm p++; 1435231200Smm } 1436231200Smm tm = localtime(&t); 1437231200Smm nsec = tm->tm_sec + rem / NS_UNIT; 1438231200Smm if (rmode & 4) 1439231200Smm { 1440231200Smm tm->tm_sec++; 1441231200Smm t = mktime(tm); 1442231200Smm } 1443231200Smm if (i == 3) 1444231200Smm { 1445231200Smm rar->mtime = t; 1446231200Smm rar->mnsec = nsec; 1447231200Smm } 1448231200Smm else if (i == 2) 1449231200Smm { 1450231200Smm rar->ctime = t; 1451231200Smm rar->cnsec = nsec; 1452231200Smm } 1453231200Smm else if (i == 1) 1454231200Smm { 1455231200Smm rar->atime = t; 1456231200Smm rar->ansec = nsec; 1457231200Smm } 1458231200Smm else 1459231200Smm { 1460231200Smm rar->arctime = t; 1461231200Smm rar->arcnsec = nsec; 1462231200Smm } 1463231200Smm } 1464231200Smm } 1465231200Smm return (0); 1466231200Smm} 1467231200Smm 1468231200Smmstatic int 1469231200Smmread_symlink_stored(struct archive_read *a, struct archive_entry *entry, 1470231200Smm struct archive_string_conv *sconv) 1471231200Smm{ 1472231200Smm const void *h; 1473231200Smm const char *p; 1474231200Smm struct rar *rar; 1475231200Smm int ret = (ARCHIVE_OK); 1476231200Smm 1477231200Smm rar = (struct rar *)(a->format->data); 1478231200Smm if ((h = __archive_read_ahead(a, rar->packed_size, NULL)) == NULL) 1479231200Smm return (ARCHIVE_FATAL); 1480231200Smm p = h; 1481231200Smm 1482231200Smm if (archive_entry_copy_symlink_l(entry, p, rar->packed_size, sconv)) 1483231200Smm { 1484231200Smm if (errno == ENOMEM) 1485231200Smm { 1486231200Smm archive_set_error(&a->archive, ENOMEM, 1487231200Smm "Can't allocate memory for link"); 1488231200Smm return (ARCHIVE_FATAL); 1489231200Smm } 1490231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1491231200Smm "link cannot be converted from %s to current locale.", 1492231200Smm archive_string_conversion_charset_name(sconv)); 1493231200Smm ret = (ARCHIVE_WARN); 1494231200Smm } 1495231200Smm __archive_read_consume(a, rar->packed_size); 1496231200Smm return ret; 1497231200Smm} 1498231200Smm 1499231200Smmstatic int 1500231200Smmread_data_stored(struct archive_read *a, const void **buff, size_t *size, 1501231200Smm int64_t *offset) 1502231200Smm{ 1503231200Smm struct rar *rar; 1504231200Smm ssize_t bytes_avail; 1505231200Smm 1506231200Smm rar = (struct rar *)(a->format->data); 1507231200Smm if (rar->bytes_remaining == 0) 1508231200Smm { 1509231200Smm *buff = NULL; 1510231200Smm *size = 0; 1511231200Smm *offset = rar->offset; 1512231200Smm if (rar->file_crc != rar->crc_calculated) { 1513231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1514231200Smm "File CRC error"); 1515231200Smm return (ARCHIVE_FATAL); 1516231200Smm } 1517231200Smm rar->entry_eof = 1; 1518231200Smm return (ARCHIVE_EOF); 1519231200Smm } 1520231200Smm 1521231200Smm *buff = __archive_read_ahead(a, 1, &bytes_avail); 1522231200Smm if (bytes_avail <= 0) 1523231200Smm { 1524231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1525231200Smm "Truncated RAR file data"); 1526231200Smm return (ARCHIVE_FATAL); 1527231200Smm } 1528231200Smm if (bytes_avail > rar->bytes_remaining) 1529231200Smm bytes_avail = rar->bytes_remaining; 1530231200Smm 1531231200Smm *size = bytes_avail; 1532231200Smm *offset = rar->offset; 1533231200Smm rar->offset += bytes_avail; 1534231200Smm rar->bytes_remaining -= bytes_avail; 1535231200Smm rar->bytes_unconsumed = bytes_avail; 1536231200Smm /* Calculate File CRC. */ 1537231200Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, bytes_avail); 1538231200Smm return (ARCHIVE_OK); 1539231200Smm} 1540231200Smm 1541231200Smmstatic int 1542231200Smmread_data_compressed(struct archive_read *a, const void **buff, size_t *size, 1543231200Smm int64_t *offset) 1544231200Smm{ 1545231200Smm struct rar *rar; 1546231200Smm int64_t start, end, actualend; 1547231200Smm size_t bs; 1548231200Smm int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i; 1549231200Smm 1550231200Smm rar = (struct rar *)(a->format->data); 1551231200Smm 1552231200Smm do { 1553231200Smm if (!rar->valid) 1554231200Smm return (ARCHIVE_FATAL); 1555231200Smm if (rar->ppmd_eod || 1556231200Smm (rar->dictionary_size && rar->offset >= rar->unp_size)) 1557231200Smm { 1558231200Smm if (rar->unp_offset > 0) { 1559231200Smm /* 1560231200Smm * We have unprocessed extracted data. write it out. 1561231200Smm */ 1562231200Smm *buff = rar->unp_buffer; 1563231200Smm *size = rar->unp_offset; 1564231200Smm *offset = rar->offset_outgoing; 1565231200Smm rar->offset_outgoing += *size; 1566231200Smm /* Calculate File CRC. */ 1567231200Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size); 1568231200Smm rar->unp_offset = 0; 1569231200Smm return (ARCHIVE_OK); 1570231200Smm } 1571231200Smm *buff = NULL; 1572231200Smm *size = 0; 1573231200Smm *offset = rar->offset; 1574231200Smm if (rar->file_crc != rar->crc_calculated) { 1575231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1576231200Smm "File CRC error"); 1577231200Smm return (ARCHIVE_FATAL); 1578231200Smm } 1579231200Smm rar->entry_eof = 1; 1580231200Smm return (ARCHIVE_EOF); 1581231200Smm } 1582231200Smm 1583231200Smm if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0) 1584231200Smm { 1585231200Smm if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) 1586231200Smm bs = rar->unp_buffer_size - rar->unp_offset; 1587231200Smm else 1588231200Smm bs = rar->bytes_uncopied; 1589231200Smm ret = copy_from_lzss_window(a, buff, rar->offset, bs); 1590231200Smm if (ret != ARCHIVE_OK) 1591231200Smm return (ret); 1592231200Smm rar->offset += bs; 1593231200Smm rar->bytes_uncopied -= bs; 1594231200Smm if (*buff != NULL) { 1595231200Smm rar->unp_offset = 0; 1596231200Smm *size = rar->unp_buffer_size; 1597231200Smm *offset = rar->offset_outgoing; 1598231200Smm rar->offset_outgoing += *size; 1599231200Smm /* Calculate File CRC. */ 1600231200Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size); 1601231200Smm return (ret); 1602231200Smm } 1603231200Smm continue; 1604231200Smm } 1605231200Smm 1606231200Smm if (!rar->br.next_in && 1607231200Smm (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN) 1608231200Smm return (ret); 1609231200Smm if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN))) 1610231200Smm return (ret); 1611231200Smm 1612231200Smm if (rar->is_ppmd_block) 1613231200Smm { 1614231200Smm if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1615231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1616231200Smm { 1617231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1618231200Smm "Invalid symbol"); 1619231200Smm return (ARCHIVE_FATAL); 1620231200Smm } 1621231200Smm if(sym != rar->ppmd_escape) 1622231200Smm { 1623231200Smm lzss_emit_literal(rar, sym); 1624231200Smm rar->bytes_uncopied++; 1625231200Smm } 1626231200Smm else 1627231200Smm { 1628231200Smm if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1629231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1630231200Smm { 1631231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1632231200Smm "Invalid symbol"); 1633231200Smm return (ARCHIVE_FATAL); 1634231200Smm } 1635231200Smm 1636231200Smm switch(code) 1637231200Smm { 1638231200Smm case 0: 1639231200Smm rar->start_new_table = 1; 1640231200Smm return read_data_compressed(a, buff, size, offset); 1641231200Smm 1642231200Smm case 2: 1643231200Smm rar->ppmd_eod = 1;/* End Of ppmd Data. */ 1644231200Smm continue; 1645231200Smm 1646231200Smm case 3: 1647231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1648231200Smm "Parsing filters is unsupported."); 1649231200Smm return (ARCHIVE_FAILED); 1650231200Smm 1651231200Smm case 4: 1652231200Smm lzss_offset = 0; 1653231200Smm for (i = 2; i >= 0; i--) 1654231200Smm { 1655231200Smm if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1656231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1657231200Smm { 1658231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1659231200Smm "Invalid symbol"); 1660231200Smm return (ARCHIVE_FATAL); 1661231200Smm } 1662231200Smm lzss_offset |= code << (i * 8); 1663231200Smm } 1664231200Smm if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1665231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1666231200Smm { 1667231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1668231200Smm "Invalid symbol"); 1669231200Smm return (ARCHIVE_FATAL); 1670231200Smm } 1671231200Smm lzss_emit_match(rar, lzss_offset + 2, length + 32); 1672231200Smm rar->bytes_uncopied += length + 32; 1673231200Smm break; 1674231200Smm 1675231200Smm case 5: 1676231200Smm if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1677231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1678231200Smm { 1679231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1680231200Smm "Invalid symbol"); 1681231200Smm return (ARCHIVE_FATAL); 1682231200Smm } 1683231200Smm lzss_emit_match(rar, 1, length + 4); 1684231200Smm rar->bytes_uncopied += length + 4; 1685231200Smm break; 1686231200Smm 1687231200Smm default: 1688231200Smm lzss_emit_literal(rar, sym); 1689231200Smm rar->bytes_uncopied++; 1690231200Smm } 1691231200Smm } 1692231200Smm } 1693231200Smm else 1694231200Smm { 1695231200Smm start = rar->offset; 1696231200Smm end = start + rar->dictionary_size; 1697231200Smm rar->filterstart = INT64_MAX; 1698231200Smm 1699231200Smm if ((actualend = expand(a, end)) < 0) 1700231200Smm return ((int)actualend); 1701231200Smm 1702231200Smm rar->bytes_uncopied = actualend - start; 1703231200Smm if (rar->bytes_uncopied == 0) { 1704231200Smm /* Broken RAR files cause this case. 1705231200Smm * NOTE: If this case were possible on a normal RAR file 1706231200Smm * we would find out where it was actually bad and 1707231200Smm * what we would do to solve it. */ 1708231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1709231200Smm "Internal error extracting RAR file"); 1710231200Smm return (ARCHIVE_FATAL); 1711231200Smm } 1712231200Smm } 1713231200Smm if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) 1714231200Smm bs = rar->unp_buffer_size - rar->unp_offset; 1715231200Smm else 1716231200Smm bs = rar->bytes_uncopied; 1717231200Smm ret = copy_from_lzss_window(a, buff, rar->offset, bs); 1718231200Smm if (ret != ARCHIVE_OK) 1719231200Smm return (ret); 1720231200Smm rar->offset += bs; 1721231200Smm rar->bytes_uncopied -= bs; 1722231200Smm /* 1723231200Smm * If *buff is NULL, it means unp_buffer is not full. 1724231200Smm * So we have to continue extracting a RAR file. 1725231200Smm */ 1726231200Smm } while (*buff == NULL); 1727231200Smm 1728231200Smm rar->unp_offset = 0; 1729231200Smm *size = rar->unp_buffer_size; 1730231200Smm *offset = rar->offset_outgoing; 1731231200Smm rar->offset_outgoing += *size; 1732231200Smm /* Calculate File CRC. */ 1733231200Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size); 1734231200Smm return ret; 1735231200Smm} 1736231200Smm 1737231200Smmstatic int 1738231200Smmparse_codes(struct archive_read *a) 1739231200Smm{ 1740231200Smm int i, j, val, n, r; 1741231200Smm unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags; 1742231200Smm unsigned int maxorder; 1743231200Smm struct huffman_code precode; 1744231200Smm struct rar *rar = (struct rar *)(a->format->data); 1745231200Smm struct rar_br *br = &(rar->br); 1746231200Smm 1747231200Smm free_codes(a); 1748231200Smm 1749231200Smm /* Skip to the next byte */ 1750231200Smm rar_br_consume_unalined_bits(br); 1751231200Smm 1752231200Smm /* PPMd block flag */ 1753231200Smm if (!rar_br_read_ahead(a, br, 1)) 1754231200Smm goto truncated_data; 1755231200Smm if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0) 1756231200Smm { 1757231200Smm rar_br_consume(br, 1); 1758231200Smm if (!rar_br_read_ahead(a, br, 7)) 1759231200Smm goto truncated_data; 1760231200Smm ppmd_flags = rar_br_bits(br, 7); 1761231200Smm rar_br_consume(br, 7); 1762231200Smm 1763231200Smm /* Memory is allocated in MB */ 1764231200Smm if (ppmd_flags & 0x20) 1765231200Smm { 1766231200Smm if (!rar_br_read_ahead(a, br, 8)) 1767231200Smm goto truncated_data; 1768231200Smm rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20; 1769231200Smm rar_br_consume(br, 8); 1770231200Smm } 1771231200Smm 1772231200Smm if (ppmd_flags & 0x40) 1773231200Smm { 1774231200Smm if (!rar_br_read_ahead(a, br, 8)) 1775231200Smm goto truncated_data; 1776231200Smm rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8); 1777231200Smm rar_br_consume(br, 8); 1778231200Smm } 1779231200Smm else 1780231200Smm rar->ppmd_escape = 2; 1781231200Smm 1782231200Smm if (ppmd_flags & 0x20) 1783231200Smm { 1784231200Smm maxorder = (ppmd_flags & 0x1F) + 1; 1785231200Smm if(maxorder > 16) 1786231200Smm maxorder = 16 + (maxorder - 16) * 3; 1787231200Smm 1788231200Smm if (maxorder == 1) 1789231200Smm { 1790231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1791231200Smm "Truncated RAR file data"); 1792231200Smm return (ARCHIVE_FATAL); 1793231200Smm } 1794231200Smm 1795231200Smm /* Make sure ppmd7_contest is freed before Ppmd7_Construct 1796231200Smm * because reading a broken file cause this abnormal sequence. */ 1797231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 1798231200Smm 1799231200Smm rar->bytein.a = a; 1800231200Smm rar->bytein.Read = &ppmd_read; 1801231200Smm __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec); 1802231200Smm rar->range_dec.Stream = &rar->bytein; 1803231200Smm __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context); 1804231200Smm 1805231200Smm if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context, 1806231200Smm rar->dictionary_size, &g_szalloc)) 1807231200Smm { 1808231200Smm archive_set_error(&a->archive, ENOMEM, 1809231200Smm "Out of memory"); 1810231200Smm return (ARCHIVE_FATAL); 1811231200Smm } 1812231200Smm if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) 1813231200Smm { 1814231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1815231200Smm "Unable to initialize PPMd range decoder"); 1816231200Smm return (ARCHIVE_FATAL); 1817231200Smm } 1818231200Smm __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder); 1819231200Smm rar->ppmd_valid = 1; 1820231200Smm } 1821231200Smm else 1822231200Smm { 1823231200Smm if (!rar->ppmd_valid) { 1824231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1825231200Smm "Invalid PPMd sequence"); 1826231200Smm return (ARCHIVE_FATAL); 1827231200Smm } 1828231200Smm if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) 1829231200Smm { 1830231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1831231200Smm "Unable to initialize PPMd range decoder"); 1832231200Smm return (ARCHIVE_FATAL); 1833231200Smm } 1834231200Smm } 1835231200Smm } 1836231200Smm else 1837231200Smm { 1838231200Smm rar_br_consume(br, 1); 1839231200Smm 1840231200Smm /* Keep existing table flag */ 1841231200Smm if (!rar_br_read_ahead(a, br, 1)) 1842231200Smm goto truncated_data; 1843231200Smm if (!rar_br_bits(br, 1)) 1844231200Smm memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); 1845231200Smm rar_br_consume(br, 1); 1846231200Smm 1847231200Smm memset(&bitlengths, 0, sizeof(bitlengths)); 1848231200Smm for (i = 0; i < MAX_SYMBOLS;) 1849231200Smm { 1850231200Smm if (!rar_br_read_ahead(a, br, 4)) 1851231200Smm goto truncated_data; 1852231200Smm bitlengths[i++] = rar_br_bits(br, 4); 1853231200Smm rar_br_consume(br, 4); 1854231200Smm if (bitlengths[i-1] == 0xF) 1855231200Smm { 1856231200Smm if (!rar_br_read_ahead(a, br, 4)) 1857231200Smm goto truncated_data; 1858231200Smm zerocount = rar_br_bits(br, 4); 1859231200Smm rar_br_consume(br, 4); 1860231200Smm if (zerocount) 1861231200Smm { 1862231200Smm i--; 1863231200Smm for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++) 1864231200Smm bitlengths[i++] = 0; 1865231200Smm } 1866231200Smm } 1867231200Smm } 1868231200Smm 1869231200Smm memset(&precode, 0, sizeof(precode)); 1870231200Smm r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH); 1871231200Smm if (r != ARCHIVE_OK) { 1872231200Smm free(precode.tree); 1873231200Smm free(precode.table); 1874231200Smm return (r); 1875231200Smm } 1876231200Smm 1877231200Smm for (i = 0; i < HUFFMAN_TABLE_SIZE;) 1878231200Smm { 1879231200Smm if ((val = read_next_symbol(a, &precode)) < 0) { 1880231200Smm free(precode.tree); 1881231200Smm free(precode.table); 1882231200Smm return (ARCHIVE_FATAL); 1883231200Smm } 1884231200Smm if (val < 16) 1885231200Smm { 1886231200Smm rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF; 1887231200Smm i++; 1888231200Smm } 1889231200Smm else if (val < 18) 1890231200Smm { 1891231200Smm if (i == 0) 1892231200Smm { 1893231200Smm free(precode.tree); 1894231200Smm free(precode.table); 1895231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1896231200Smm "Internal error extracting RAR file."); 1897231200Smm return (ARCHIVE_FATAL); 1898231200Smm } 1899231200Smm 1900231200Smm if(val == 16) { 1901231200Smm if (!rar_br_read_ahead(a, br, 3)) { 1902231200Smm free(precode.tree); 1903231200Smm free(precode.table); 1904231200Smm goto truncated_data; 1905231200Smm } 1906231200Smm n = rar_br_bits(br, 3) + 3; 1907231200Smm rar_br_consume(br, 3); 1908231200Smm } else { 1909231200Smm if (!rar_br_read_ahead(a, br, 7)) { 1910231200Smm free(precode.tree); 1911231200Smm free(precode.table); 1912231200Smm goto truncated_data; 1913231200Smm } 1914231200Smm n = rar_br_bits(br, 7) + 11; 1915231200Smm rar_br_consume(br, 7); 1916231200Smm } 1917231200Smm 1918231200Smm for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) 1919231200Smm { 1920231200Smm rar->lengthtable[i] = rar->lengthtable[i-1]; 1921231200Smm i++; 1922231200Smm } 1923231200Smm } 1924231200Smm else 1925231200Smm { 1926231200Smm if(val == 18) { 1927231200Smm if (!rar_br_read_ahead(a, br, 3)) { 1928231200Smm free(precode.tree); 1929231200Smm free(precode.table); 1930231200Smm goto truncated_data; 1931231200Smm } 1932231200Smm n = rar_br_bits(br, 3) + 3; 1933231200Smm rar_br_consume(br, 3); 1934231200Smm } else { 1935231200Smm if (!rar_br_read_ahead(a, br, 7)) { 1936231200Smm free(precode.tree); 1937231200Smm free(precode.table); 1938231200Smm goto truncated_data; 1939231200Smm } 1940231200Smm n = rar_br_bits(br, 7) + 11; 1941231200Smm rar_br_consume(br, 7); 1942231200Smm } 1943231200Smm 1944231200Smm for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) 1945231200Smm rar->lengthtable[i++] = 0; 1946231200Smm } 1947231200Smm } 1948231200Smm free(precode.tree); 1949231200Smm free(precode.table); 1950231200Smm 1951231200Smm r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE, 1952231200Smm MAX_SYMBOL_LENGTH); 1953231200Smm if (r != ARCHIVE_OK) 1954231200Smm return (r); 1955231200Smm r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE], 1956231200Smm OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); 1957231200Smm if (r != ARCHIVE_OK) 1958231200Smm return (r); 1959231200Smm r = create_code(a, &rar->lowoffsetcode, 1960231200Smm &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE], 1961231200Smm LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); 1962231200Smm if (r != ARCHIVE_OK) 1963231200Smm return (r); 1964231200Smm r = create_code(a, &rar->lengthcode, 1965231200Smm &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE + 1966231200Smm LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH); 1967231200Smm if (r != ARCHIVE_OK) 1968231200Smm return (r); 1969231200Smm } 1970231200Smm 1971231200Smm if (!rar->dictionary_size || !rar->lzss.window) 1972231200Smm { 1973231200Smm /* Seems as though dictionary sizes are not used. Even so, minimize 1974231200Smm * memory usage as much as possible. 1975231200Smm */ 1976231200Smm if (rar->unp_size >= DICTIONARY_MAX_SIZE) 1977231200Smm rar->dictionary_size = DICTIONARY_MAX_SIZE; 1978231200Smm else 1979231200Smm rar->dictionary_size = rar_fls(rar->unp_size) << 1; 1980231200Smm rar->lzss.window = (unsigned char *)realloc(rar->lzss.window, 1981231200Smm rar->dictionary_size); 1982231200Smm if (rar->lzss.window == NULL) { 1983231200Smm archive_set_error(&a->archive, ENOMEM, 1984231200Smm "Unable to allocate memory for uncompressed data."); 1985231200Smm return (ARCHIVE_FATAL); 1986231200Smm } 1987231200Smm memset(rar->lzss.window, 0, rar->dictionary_size); 1988231200Smm rar->lzss.mask = rar->dictionary_size - 1; 1989231200Smm } 1990231200Smm 1991231200Smm rar->start_new_table = 0; 1992231200Smm return (ARCHIVE_OK); 1993231200Smmtruncated_data: 1994231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1995231200Smm "Truncated RAR file data"); 1996231200Smm rar->valid = 0; 1997231200Smm return (ARCHIVE_FATAL); 1998231200Smm} 1999231200Smm 2000231200Smmstatic void 2001231200Smmfree_codes(struct archive_read *a) 2002231200Smm{ 2003231200Smm struct rar *rar = (struct rar *)(a->format->data); 2004231200Smm free(rar->maincode.tree); 2005231200Smm free(rar->offsetcode.tree); 2006231200Smm free(rar->lowoffsetcode.tree); 2007231200Smm free(rar->lengthcode.tree); 2008231200Smm free(rar->maincode.table); 2009231200Smm free(rar->offsetcode.table); 2010231200Smm free(rar->lowoffsetcode.table); 2011231200Smm free(rar->lengthcode.table); 2012231200Smm memset(&rar->maincode, 0, sizeof(rar->maincode)); 2013231200Smm memset(&rar->offsetcode, 0, sizeof(rar->offsetcode)); 2014231200Smm memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode)); 2015231200Smm memset(&rar->lengthcode, 0, sizeof(rar->lengthcode)); 2016231200Smm} 2017231200Smm 2018231200Smm 2019231200Smmstatic int 2020231200Smmread_next_symbol(struct archive_read *a, struct huffman_code *code) 2021231200Smm{ 2022231200Smm unsigned char bit; 2023231200Smm unsigned int bits; 2024231200Smm int length, value, node; 2025231200Smm struct rar *rar; 2026231200Smm struct rar_br *br; 2027231200Smm 2028231200Smm if (!code->table) 2029231200Smm { 2030231200Smm if (make_table(a, code) != (ARCHIVE_OK)) 2031231200Smm return -1; 2032231200Smm } 2033231200Smm 2034231200Smm rar = (struct rar *)(a->format->data); 2035231200Smm br = &(rar->br); 2036231200Smm 2037231200Smm /* Look ahead (peek) at bits */ 2038231200Smm if (!rar_br_read_ahead(a, br, code->tablesize)) { 2039231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2040231200Smm "Truncated RAR file data"); 2041231200Smm rar->valid = 0; 2042231200Smm return -1; 2043231200Smm } 2044231200Smm bits = rar_br_bits(br, code->tablesize); 2045231200Smm 2046231200Smm length = code->table[bits].length; 2047231200Smm value = code->table[bits].value; 2048231200Smm 2049231200Smm if (length < 0) 2050231200Smm { 2051231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2052231200Smm "Invalid prefix code in bitstream"); 2053231200Smm return -1; 2054231200Smm } 2055231200Smm 2056231200Smm if (length <= code->tablesize) 2057231200Smm { 2058231200Smm /* Skip length bits */ 2059231200Smm rar_br_consume(br, length); 2060231200Smm return value; 2061231200Smm } 2062231200Smm 2063231200Smm /* Skip tablesize bits */ 2064231200Smm rar_br_consume(br, code->tablesize); 2065231200Smm 2066231200Smm node = value; 2067231200Smm while (!(code->tree[node].branches[0] == 2068231200Smm code->tree[node].branches[1])) 2069231200Smm { 2070231200Smm if (!rar_br_read_ahead(a, br, 1)) { 2071231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2072231200Smm "Truncated RAR file data"); 2073231200Smm rar->valid = 0; 2074231200Smm return -1; 2075231200Smm } 2076231200Smm bit = rar_br_bits(br, 1); 2077231200Smm rar_br_consume(br, 1); 2078231200Smm 2079231200Smm if (code->tree[node].branches[bit] < 0) 2080231200Smm { 2081231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2082231200Smm "Invalid prefix code in bitstream"); 2083231200Smm return -1; 2084231200Smm } 2085231200Smm node = code->tree[node].branches[bit]; 2086231200Smm } 2087231200Smm 2088231200Smm return code->tree[node].branches[0]; 2089231200Smm} 2090231200Smm 2091231200Smmstatic int 2092231200Smmcreate_code(struct archive_read *a, struct huffman_code *code, 2093231200Smm unsigned char *lengths, int numsymbols, char maxlength) 2094231200Smm{ 2095231200Smm int i, j, codebits = 0, symbolsleft = numsymbols; 2096231200Smm 2097231200Smm if (new_node(code) < 0) { 2098231200Smm archive_set_error(&a->archive, ENOMEM, 2099231200Smm "Unable to allocate memory for node data."); 2100231200Smm return (ARCHIVE_FATAL); 2101231200Smm } 2102231200Smm code->numentries = 1; 2103231200Smm code->minlength = INT_MAX; 2104231200Smm code->maxlength = INT_MIN; 2105231200Smm codebits = 0; 2106231200Smm for(i = 1; i <= maxlength; i++) 2107231200Smm { 2108231200Smm for(j = 0; j < numsymbols; j++) 2109231200Smm { 2110231200Smm if (lengths[j] != i) continue; 2111231200Smm if (add_value(a, code, j, codebits, i) != ARCHIVE_OK) 2112231200Smm return (ARCHIVE_FATAL); 2113231200Smm codebits++; 2114231200Smm if (--symbolsleft <= 0) { break; break; } 2115231200Smm } 2116231200Smm codebits <<= 1; 2117231200Smm } 2118231200Smm return (ARCHIVE_OK); 2119231200Smm} 2120231200Smm 2121231200Smmstatic int 2122231200Smmadd_value(struct archive_read *a, struct huffman_code *code, int value, 2123231200Smm int codebits, int length) 2124231200Smm{ 2125231200Smm int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode; 2126231200Smm 2127231200Smm free(code->table); 2128231200Smm code->table = NULL; 2129231200Smm 2130231200Smm if(length > code->maxlength) 2131231200Smm code->maxlength = length; 2132231200Smm if(length < code->minlength) 2133231200Smm code->minlength = length; 2134231200Smm 2135231200Smm repeatpos = -1; 2136231200Smm if (repeatpos == 0 || (repeatpos >= 0 2137231200Smm && (((codebits >> (repeatpos - 1)) & 3) == 0 2138231200Smm || ((codebits >> (repeatpos - 1)) & 3) == 3))) 2139231200Smm { 2140231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2141231200Smm "Invalid repeat position"); 2142231200Smm return (ARCHIVE_FATAL); 2143231200Smm } 2144231200Smm 2145231200Smm lastnode = 0; 2146231200Smm for (bitpos = length - 1; bitpos >= 0; bitpos--) 2147231200Smm { 2148231200Smm bit = (codebits >> bitpos) & 1; 2149231200Smm 2150231200Smm /* Leaf node check */ 2151231200Smm if (code->tree[lastnode].branches[0] == 2152231200Smm code->tree[lastnode].branches[1]) 2153231200Smm { 2154231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2155231200Smm "Prefix found"); 2156231200Smm return (ARCHIVE_FATAL); 2157231200Smm } 2158231200Smm 2159231200Smm if (bitpos == repeatpos) 2160231200Smm { 2161231200Smm /* Open branch check */ 2162231200Smm if (!(code->tree[lastnode].branches[bit] < 0)) 2163231200Smm { 2164231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2165231200Smm "Invalid repeating code"); 2166231200Smm return (ARCHIVE_FATAL); 2167231200Smm } 2168231200Smm 2169231200Smm if ((repeatnode = new_node(code)) < 0) { 2170231200Smm archive_set_error(&a->archive, ENOMEM, 2171231200Smm "Unable to allocate memory for node data."); 2172231200Smm return (ARCHIVE_FATAL); 2173231200Smm } 2174231200Smm if ((nextnode = new_node(code)) < 0) { 2175231200Smm archive_set_error(&a->archive, ENOMEM, 2176231200Smm "Unable to allocate memory for node data."); 2177231200Smm return (ARCHIVE_FATAL); 2178231200Smm } 2179231200Smm 2180231200Smm /* Set branches */ 2181231200Smm code->tree[lastnode].branches[bit] = repeatnode; 2182231200Smm code->tree[repeatnode].branches[bit] = repeatnode; 2183231200Smm code->tree[repeatnode].branches[bit^1] = nextnode; 2184231200Smm lastnode = nextnode; 2185231200Smm 2186231200Smm bitpos++; /* terminating bit already handled, skip it */ 2187231200Smm } 2188231200Smm else 2189231200Smm { 2190231200Smm /* Open branch check */ 2191231200Smm if (code->tree[lastnode].branches[bit] < 0) 2192231200Smm { 2193231200Smm if (new_node(code) < 0) { 2194231200Smm archive_set_error(&a->archive, ENOMEM, 2195231200Smm "Unable to allocate memory for node data."); 2196231200Smm return (ARCHIVE_FATAL); 2197231200Smm } 2198231200Smm code->tree[lastnode].branches[bit] = code->numentries++; 2199231200Smm } 2200231200Smm 2201231200Smm /* set to branch */ 2202231200Smm lastnode = code->tree[lastnode].branches[bit]; 2203231200Smm } 2204231200Smm } 2205231200Smm 2206231200Smm if (!(code->tree[lastnode].branches[0] == -1 2207231200Smm && code->tree[lastnode].branches[1] == -2)) 2208231200Smm { 2209231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2210231200Smm "Prefix found"); 2211231200Smm return (ARCHIVE_FATAL); 2212231200Smm } 2213231200Smm 2214231200Smm /* Set leaf value */ 2215231200Smm code->tree[lastnode].branches[0] = value; 2216231200Smm code->tree[lastnode].branches[1] = value; 2217231200Smm 2218231200Smm return (ARCHIVE_OK); 2219231200Smm} 2220231200Smm 2221231200Smmstatic int 2222231200Smmnew_node(struct huffman_code *code) 2223231200Smm{ 2224231200Smm code->tree = (struct huffman_tree_node *)realloc(code->tree, 2225231200Smm (code->numentries + 1) * sizeof(*code->tree)); 2226231200Smm if (code->tree == NULL) 2227231200Smm return (-1); 2228231200Smm code->tree[code->numentries].branches[0] = -1; 2229231200Smm code->tree[code->numentries].branches[1] = -2; 2230231200Smm return 1; 2231231200Smm} 2232231200Smm 2233231200Smmstatic int 2234231200Smmmake_table(struct archive_read *a, struct huffman_code *code) 2235231200Smm{ 2236231200Smm if (code->maxlength < code->minlength || code->maxlength > 10) 2237231200Smm code->tablesize = 10; 2238231200Smm else 2239231200Smm code->tablesize = code->maxlength; 2240231200Smm 2241231200Smm code->table = 2242231200Smm (struct huffman_table_entry *)malloc(sizeof(*code->table) 2243231200Smm * (1 << code->tablesize)); 2244231200Smm 2245231200Smm return make_table_recurse(a, code, 0, code->table, 0, code->tablesize); 2246231200Smm} 2247231200Smm 2248231200Smmstatic int 2249231200Smmmake_table_recurse(struct archive_read *a, struct huffman_code *code, int node, 2250231200Smm struct huffman_table_entry *table, int depth, 2251231200Smm int maxdepth) 2252231200Smm{ 2253231200Smm int currtablesize, i, ret = (ARCHIVE_OK); 2254231200Smm 2255231200Smm if (!code->tree) 2256231200Smm { 2257231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2258231200Smm "Huffman tree was not created."); 2259231200Smm return (ARCHIVE_FATAL); 2260231200Smm } 2261231200Smm if (node < 0 || node >= code->numentries) 2262231200Smm { 2263231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2264231200Smm "Invalid location to Huffman tree specified."); 2265231200Smm return (ARCHIVE_FATAL); 2266231200Smm } 2267231200Smm 2268231200Smm currtablesize = 1 << (maxdepth - depth); 2269231200Smm 2270231200Smm if (code->tree[node].branches[0] == 2271231200Smm code->tree[node].branches[1]) 2272231200Smm { 2273231200Smm for(i = 0; i < currtablesize; i++) 2274231200Smm { 2275231200Smm table[i].length = depth; 2276231200Smm table[i].value = code->tree[node].branches[0]; 2277231200Smm } 2278231200Smm } 2279231200Smm else if (node < 0) 2280231200Smm { 2281231200Smm for(i = 0; i < currtablesize; i++) 2282231200Smm table[i].length = -1; 2283231200Smm } 2284231200Smm else 2285231200Smm { 2286231200Smm if(depth == maxdepth) 2287231200Smm { 2288231200Smm table[0].length = maxdepth + 1; 2289231200Smm table[0].value = node; 2290231200Smm } 2291231200Smm else 2292231200Smm { 2293231200Smm ret |= make_table_recurse(a, code, code->tree[node].branches[0], table, 2294231200Smm depth + 1, maxdepth); 2295231200Smm ret |= make_table_recurse(a, code, code->tree[node].branches[1], 2296231200Smm table + currtablesize / 2, depth + 1, maxdepth); 2297231200Smm } 2298231200Smm } 2299231200Smm return ret; 2300231200Smm} 2301231200Smm 2302231200Smmstatic int64_t 2303231200Smmexpand(struct archive_read *a, int64_t end) 2304231200Smm{ 2305231200Smm static const unsigned char lengthbases[] = 2306231200Smm { 0, 1, 2, 3, 4, 5, 6, 2307231200Smm 7, 8, 10, 12, 14, 16, 20, 2308231200Smm 24, 28, 32, 40, 48, 56, 64, 2309231200Smm 80, 96, 112, 128, 160, 192, 224 }; 2310231200Smm static const unsigned char lengthbits[] = 2311231200Smm { 0, 0, 0, 0, 0, 0, 0, 2312231200Smm 0, 1, 1, 1, 1, 2, 2, 2313231200Smm 2, 2, 3, 3, 3, 3, 4, 2314231200Smm 4, 4, 4, 5, 5, 5, 5 }; 2315231200Smm static const unsigned int offsetbases[] = 2316231200Smm { 0, 1, 2, 3, 4, 6, 2317231200Smm 8, 12, 16, 24, 32, 48, 2318231200Smm 64, 96, 128, 192, 256, 384, 2319231200Smm 512, 768, 1024, 1536, 2048, 3072, 2320231200Smm 4096, 6144, 8192, 12288, 16384, 24576, 2321231200Smm 32768, 49152, 65536, 98304, 131072, 196608, 2322231200Smm 262144, 327680, 393216, 458752, 524288, 589824, 2323231200Smm 655360, 720896, 786432, 851968, 917504, 983040, 2324231200Smm 1048576, 1310720, 1572864, 1835008, 2097152, 2359296, 2325231200Smm 2621440, 2883584, 3145728, 3407872, 3670016, 3932160 }; 2326231200Smm static const unsigned char offsetbits[] = 2327231200Smm { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 2328231200Smm 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 2329231200Smm 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 2330231200Smm 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2331231200Smm 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; 2332231200Smm static const unsigned char shortbases[] = 2333231200Smm { 0, 4, 8, 16, 32, 64, 128, 192 }; 2334231200Smm static const unsigned char shortbits[] = 2335231200Smm { 2, 2, 3, 4, 5, 6, 6, 6 }; 2336231200Smm 2337231200Smm int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol; 2338231200Smm unsigned char newfile; 2339231200Smm struct rar *rar = (struct rar *)(a->format->data); 2340231200Smm struct rar_br *br = &(rar->br); 2341231200Smm 2342231200Smm if (rar->filterstart < end) 2343231200Smm end = rar->filterstart; 2344231200Smm 2345231200Smm while (1) 2346231200Smm { 2347231200Smm if (rar->output_last_match && 2348231200Smm lzss_position(&rar->lzss) + rar->lastlength <= end) 2349231200Smm { 2350231200Smm lzss_emit_match(rar, rar->lastoffset, rar->lastlength); 2351231200Smm rar->output_last_match = 0; 2352231200Smm } 2353231200Smm 2354231200Smm if(rar->is_ppmd_block || rar->output_last_match || 2355231200Smm lzss_position(&rar->lzss) >= end) 2356231200Smm return lzss_position(&rar->lzss); 2357231200Smm 2358231200Smm if ((symbol = read_next_symbol(a, &rar->maincode)) < 0) 2359231200Smm return (ARCHIVE_FATAL); 2360231200Smm rar->output_last_match = 0; 2361231200Smm 2362231200Smm if (symbol < 256) 2363231200Smm { 2364231200Smm lzss_emit_literal(rar, symbol); 2365231200Smm continue; 2366231200Smm } 2367231200Smm else if (symbol == 256) 2368231200Smm { 2369231200Smm if (!rar_br_read_ahead(a, br, 1)) 2370231200Smm goto truncated_data; 2371231200Smm newfile = !rar_br_bits(br, 1); 2372231200Smm rar_br_consume(br, 1); 2373231200Smm 2374231200Smm if(newfile) 2375231200Smm { 2376231200Smm rar->start_new_block = 1; 2377231200Smm if (!rar_br_read_ahead(a, br, 1)) 2378231200Smm goto truncated_data; 2379231200Smm rar->start_new_table = rar_br_bits(br, 1); 2380231200Smm rar_br_consume(br, 1); 2381231200Smm return lzss_position(&rar->lzss); 2382231200Smm } 2383231200Smm else 2384231200Smm { 2385231200Smm if (parse_codes(a) != ARCHIVE_OK) 2386231200Smm return (ARCHIVE_FATAL); 2387231200Smm continue; 2388231200Smm } 2389231200Smm } 2390231200Smm else if(symbol==257) 2391231200Smm { 2392231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 2393231200Smm "Parsing filters is unsupported."); 2394231200Smm return (ARCHIVE_FAILED); 2395231200Smm } 2396231200Smm else if(symbol==258) 2397231200Smm { 2398231200Smm if(rar->lastlength == 0) 2399231200Smm continue; 2400231200Smm 2401231200Smm offs = rar->lastoffset; 2402231200Smm len = rar->lastlength; 2403231200Smm } 2404231200Smm else if (symbol <= 262) 2405231200Smm { 2406231200Smm offsindex = symbol - 259; 2407231200Smm offs = rar->oldoffset[offsindex]; 2408231200Smm 2409231200Smm if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0) 2410231200Smm goto bad_data; 2411231200Smm if (lensymbol > sizeof(lengthbases)/sizeof(lengthbases[0])) 2412231200Smm goto bad_data; 2413231200Smm if (lensymbol > sizeof(lengthbits)/sizeof(lengthbits[0])) 2414231200Smm goto bad_data; 2415231200Smm len = lengthbases[lensymbol] + 2; 2416231200Smm if (lengthbits[lensymbol] > 0) { 2417231200Smm if (!rar_br_read_ahead(a, br, lengthbits[lensymbol])) 2418231200Smm goto truncated_data; 2419231200Smm len += rar_br_bits(br, lengthbits[lensymbol]); 2420231200Smm rar_br_consume(br, lengthbits[lensymbol]); 2421231200Smm } 2422231200Smm 2423231200Smm for (i = offsindex; i > 0; i--) 2424231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2425231200Smm rar->oldoffset[0] = offs; 2426231200Smm } 2427231200Smm else if(symbol<=270) 2428231200Smm { 2429231200Smm offs = shortbases[symbol-263] + 1; 2430231200Smm if(shortbits[symbol-263] > 0) { 2431231200Smm if (!rar_br_read_ahead(a, br, shortbits[symbol-263])) 2432231200Smm goto truncated_data; 2433231200Smm offs += rar_br_bits(br, shortbits[symbol-263]); 2434231200Smm rar_br_consume(br, shortbits[symbol-263]); 2435231200Smm } 2436231200Smm 2437231200Smm len = 2; 2438231200Smm 2439231200Smm for(i = 3; i > 0; i--) 2440231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2441231200Smm rar->oldoffset[0] = offs; 2442231200Smm } 2443231200Smm else 2444231200Smm { 2445231200Smm if (symbol-271 > sizeof(lengthbases)/sizeof(lengthbases[0])) 2446231200Smm goto bad_data; 2447231200Smm if (symbol-271 > sizeof(lengthbits)/sizeof(lengthbits[0])) 2448231200Smm goto bad_data; 2449231200Smm len = lengthbases[symbol-271]+3; 2450231200Smm if(lengthbits[symbol-271] > 0) { 2451231200Smm if (!rar_br_read_ahead(a, br, lengthbits[symbol-271])) 2452231200Smm goto truncated_data; 2453231200Smm len += rar_br_bits(br, lengthbits[symbol-271]); 2454231200Smm rar_br_consume(br, lengthbits[symbol-271]); 2455231200Smm } 2456231200Smm 2457231200Smm if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0) 2458231200Smm goto bad_data; 2459231200Smm if (offssymbol > sizeof(offsetbases)/sizeof(offsetbases[0])) 2460231200Smm goto bad_data; 2461231200Smm if (offssymbol > sizeof(offsetbits)/sizeof(offsetbits[0])) 2462231200Smm goto bad_data; 2463231200Smm offs = offsetbases[offssymbol]+1; 2464231200Smm if(offsetbits[offssymbol] > 0) 2465231200Smm { 2466231200Smm if(offssymbol > 9) 2467231200Smm { 2468231200Smm if(offsetbits[offssymbol] > 4) { 2469231200Smm if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4)) 2470231200Smm goto truncated_data; 2471231200Smm offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4; 2472231200Smm rar_br_consume(br, offsetbits[offssymbol] - 4); 2473231200Smm } 2474231200Smm 2475231200Smm if(rar->numlowoffsetrepeats > 0) 2476231200Smm { 2477231200Smm rar->numlowoffsetrepeats--; 2478231200Smm offs += rar->lastlowoffset; 2479231200Smm } 2480231200Smm else 2481231200Smm { 2482231200Smm if ((lowoffsetsymbol = 2483231200Smm read_next_symbol(a, &rar->lowoffsetcode)) < 0) 2484231200Smm return (ARCHIVE_FATAL); 2485231200Smm if(lowoffsetsymbol == 16) 2486231200Smm { 2487231200Smm rar->numlowoffsetrepeats = 15; 2488231200Smm offs += rar->lastlowoffset; 2489231200Smm } 2490231200Smm else 2491231200Smm { 2492231200Smm offs += lowoffsetsymbol; 2493231200Smm rar->lastlowoffset = lowoffsetsymbol; 2494231200Smm } 2495231200Smm } 2496231200Smm } 2497231200Smm else { 2498231200Smm if (!rar_br_read_ahead(a, br, offsetbits[offssymbol])) 2499231200Smm goto truncated_data; 2500231200Smm offs += rar_br_bits(br, offsetbits[offssymbol]); 2501231200Smm rar_br_consume(br, offsetbits[offssymbol]); 2502231200Smm } 2503231200Smm } 2504231200Smm 2505231200Smm if (offs >= 0x40000) 2506231200Smm len++; 2507231200Smm if (offs >= 0x2000) 2508231200Smm len++; 2509231200Smm 2510231200Smm for(i = 3; i > 0; i--) 2511231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2512231200Smm rar->oldoffset[0] = offs; 2513231200Smm } 2514231200Smm 2515231200Smm rar->lastoffset = offs; 2516231200Smm rar->lastlength = len; 2517231200Smm rar->output_last_match = 1; 2518231200Smm } 2519231200Smmtruncated_data: 2520231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2521231200Smm "Truncated RAR file data"); 2522231200Smm rar->valid = 0; 2523231200Smm return (ARCHIVE_FATAL); 2524231200Smmbad_data: 2525231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2526231200Smm "Bad RAR file data"); 2527231200Smm return (ARCHIVE_FATAL); 2528231200Smm} 2529231200Smm 2530231200Smmstatic int 2531231200Smmcopy_from_lzss_window(struct archive_read *a, const void **buffer, 2532231200Smm int64_t startpos, int length) 2533231200Smm{ 2534231200Smm int windowoffs, firstpart; 2535231200Smm struct rar *rar = (struct rar *)(a->format->data); 2536231200Smm 2537231200Smm if (!rar->unp_buffer) 2538231200Smm { 2539231200Smm if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL) 2540231200Smm { 2541231200Smm archive_set_error(&a->archive, ENOMEM, 2542231200Smm "Unable to allocate memory for uncompressed data."); 2543231200Smm return (ARCHIVE_FATAL); 2544231200Smm } 2545231200Smm } 2546231200Smm 2547231200Smm windowoffs = lzss_offset_for_position(&rar->lzss, startpos); 2548231200Smm if(windowoffs + length <= lzss_size(&rar->lzss)) 2549231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs], 2550231200Smm length); 2551231200Smm else 2552231200Smm { 2553231200Smm firstpart = lzss_size(&rar->lzss) - windowoffs; 2554231200Smm if (firstpart < 0) { 2555231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2556231200Smm "Bad RAR file data"); 2557231200Smm return (ARCHIVE_FATAL); 2558231200Smm } 2559231200Smm if (firstpart < length) { 2560231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], 2561231200Smm &rar->lzss.window[windowoffs], firstpart); 2562231200Smm memcpy(&rar->unp_buffer[rar->unp_offset + firstpart], 2563231200Smm &rar->lzss.window[0], length - firstpart); 2564231200Smm } else 2565231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], 2566231200Smm &rar->lzss.window[windowoffs], length); 2567231200Smm } 2568231200Smm rar->unp_offset += length; 2569231200Smm if (rar->unp_offset >= rar->unp_buffer_size) 2570231200Smm *buffer = rar->unp_buffer; 2571231200Smm else 2572231200Smm *buffer = NULL; 2573231200Smm return (ARCHIVE_OK); 2574231200Smm} 2575