archive_read_support_format_rar.c revision 248616
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 202248616Smmstruct data_block_offsets 203248616Smm{ 204248616Smm int64_t header_size; 205248616Smm int64_t start_offset; 206248616Smm int64_t end_offset; 207248616Smm}; 208248616Smm 209231200Smmstruct rar 210231200Smm{ 211231200Smm /* Entries from main RAR header */ 212231200Smm unsigned main_flags; 213231200Smm unsigned long file_crc; 214231200Smm char reserved1[2]; 215231200Smm char reserved2[4]; 216231200Smm char encryptver; 217231200Smm 218231200Smm /* File header entries */ 219231200Smm char compression_method; 220231200Smm unsigned file_flags; 221231200Smm int64_t packed_size; 222231200Smm int64_t unp_size; 223231200Smm time_t mtime; 224231200Smm long mnsec; 225231200Smm mode_t mode; 226231200Smm char *filename; 227248616Smm char *filename_save; 228231200Smm size_t filename_allocated; 229231200Smm 230231200Smm /* File header optional entries */ 231231200Smm char salt[8]; 232231200Smm time_t atime; 233231200Smm long ansec; 234231200Smm time_t ctime; 235231200Smm long cnsec; 236231200Smm time_t arctime; 237231200Smm long arcnsec; 238231200Smm 239231200Smm /* Fields to help with tracking decompression of files. */ 240231200Smm int64_t bytes_unconsumed; 241231200Smm int64_t bytes_remaining; 242231200Smm int64_t bytes_uncopied; 243231200Smm int64_t offset; 244231200Smm int64_t offset_outgoing; 245248616Smm int64_t offset_seek; 246231200Smm char valid; 247231200Smm unsigned int unp_offset; 248231200Smm unsigned int unp_buffer_size; 249231200Smm unsigned char *unp_buffer; 250231200Smm unsigned int dictionary_size; 251231200Smm char start_new_block; 252231200Smm char entry_eof; 253231200Smm unsigned long crc_calculated; 254231200Smm int found_first_header; 255248616Smm char has_endarc_header; 256248616Smm struct data_block_offsets *dbo; 257248616Smm unsigned int cursor; 258248616Smm unsigned int nodes; 259231200Smm 260231200Smm /* LZSS members */ 261231200Smm struct huffman_code maincode; 262231200Smm struct huffman_code offsetcode; 263231200Smm struct huffman_code lowoffsetcode; 264231200Smm struct huffman_code lengthcode; 265231200Smm unsigned char lengthtable[HUFFMAN_TABLE_SIZE]; 266231200Smm struct lzss lzss; 267231200Smm char output_last_match; 268231200Smm unsigned int lastlength; 269231200Smm unsigned int lastoffset; 270231200Smm unsigned int oldoffset[4]; 271231200Smm unsigned int lastlowoffset; 272231200Smm unsigned int numlowoffsetrepeats; 273231200Smm int64_t filterstart; 274231200Smm char start_new_table; 275231200Smm 276231200Smm /* PPMd Variant H members */ 277231200Smm char ppmd_valid; 278231200Smm char ppmd_eod; 279231200Smm char is_ppmd_block; 280231200Smm int ppmd_escape; 281231200Smm CPpmd7 ppmd7_context; 282231200Smm CPpmd7z_RangeDec range_dec; 283231200Smm IByteIn bytein; 284231200Smm 285231200Smm /* 286231200Smm * String conversion object. 287231200Smm */ 288231200Smm int init_default_conversion; 289231200Smm struct archive_string_conv *sconv_default; 290231200Smm struct archive_string_conv *opt_sconv; 291231200Smm struct archive_string_conv *sconv_utf8; 292231200Smm struct archive_string_conv *sconv_utf16be; 293231200Smm 294231200Smm /* 295231200Smm * Bit stream reader. 296231200Smm */ 297231200Smm struct rar_br { 298231200Smm#define CACHE_TYPE uint64_t 299231200Smm#define CACHE_BITS (8 * sizeof(CACHE_TYPE)) 300231200Smm /* Cache buffer. */ 301231200Smm CACHE_TYPE cache_buffer; 302231200Smm /* Indicates how many bits avail in cache_buffer. */ 303231200Smm int cache_avail; 304231200Smm ssize_t avail_in; 305231200Smm const unsigned char *next_in; 306231200Smm } br; 307231200Smm}; 308231200Smm 309231200Smmstatic int archive_read_format_rar_bid(struct archive_read *, int); 310231200Smmstatic int archive_read_format_rar_options(struct archive_read *, 311231200Smm const char *, const char *); 312231200Smmstatic int archive_read_format_rar_read_header(struct archive_read *, 313231200Smm struct archive_entry *); 314231200Smmstatic int archive_read_format_rar_read_data(struct archive_read *, 315231200Smm const void **, size_t *, int64_t *); 316231200Smmstatic int archive_read_format_rar_read_data_skip(struct archive_read *a); 317248616Smmstatic int64_t archive_read_format_rar_seek_data(struct archive_read *, int64_t, 318248616Smm int); 319231200Smmstatic int archive_read_format_rar_cleanup(struct archive_read *); 320231200Smm 321231200Smm/* Support functions */ 322231200Smmstatic int read_header(struct archive_read *, struct archive_entry *, char); 323232153Smmstatic time_t get_time(int); 324231200Smmstatic int read_exttime(const char *, struct rar *, const char *); 325231200Smmstatic int read_symlink_stored(struct archive_read *, struct archive_entry *, 326231200Smm struct archive_string_conv *); 327231200Smmstatic int read_data_stored(struct archive_read *, const void **, size_t *, 328231200Smm int64_t *); 329231200Smmstatic int read_data_compressed(struct archive_read *, const void **, size_t *, 330231200Smm int64_t *); 331231200Smmstatic int rar_br_preparation(struct archive_read *, struct rar_br *); 332231200Smmstatic int parse_codes(struct archive_read *); 333231200Smmstatic void free_codes(struct archive_read *); 334231200Smmstatic int read_next_symbol(struct archive_read *, struct huffman_code *); 335231200Smmstatic int create_code(struct archive_read *, struct huffman_code *, 336231200Smm unsigned char *, int, char); 337231200Smmstatic int add_value(struct archive_read *, struct huffman_code *, int, int, 338231200Smm int); 339231200Smmstatic int new_node(struct huffman_code *); 340231200Smmstatic int make_table(struct archive_read *, struct huffman_code *); 341231200Smmstatic int make_table_recurse(struct archive_read *, struct huffman_code *, int, 342231200Smm struct huffman_table_entry *, int, int); 343231200Smmstatic int64_t expand(struct archive_read *, int64_t); 344231200Smmstatic int copy_from_lzss_window(struct archive_read *, const void **, 345231200Smm int64_t, int); 346248616Smmstatic const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *); 347231200Smm 348231200Smm/* 349231200Smm * Bit stream reader. 350231200Smm */ 351231200Smm/* Check that the cache buffer has enough bits. */ 352231200Smm#define rar_br_has(br, n) ((br)->cache_avail >= n) 353231200Smm/* Get compressed data by bit. */ 354231200Smm#define rar_br_bits(br, n) \ 355231200Smm (((uint32_t)((br)->cache_buffer >> \ 356231200Smm ((br)->cache_avail - (n)))) & cache_masks[n]) 357231200Smm#define rar_br_bits_forced(br, n) \ 358231200Smm (((uint32_t)((br)->cache_buffer << \ 359231200Smm ((n) - (br)->cache_avail))) & cache_masks[n]) 360231200Smm/* Read ahead to make sure the cache buffer has enough compressed data we 361231200Smm * will use. 362231200Smm * True : completed, there is enough data in the cache buffer. 363231200Smm * False : there is no data in the stream. */ 364231200Smm#define rar_br_read_ahead(a, br, n) \ 365231200Smm ((rar_br_has(br, (n)) || rar_br_fillup(a, br)) || rar_br_has(br, (n))) 366231200Smm/* Notify how many bits we consumed. */ 367231200Smm#define rar_br_consume(br, n) ((br)->cache_avail -= (n)) 368231200Smm#define rar_br_consume_unalined_bits(br) ((br)->cache_avail &= ~7) 369231200Smm 370231200Smmstatic const uint32_t cache_masks[] = { 371231200Smm 0x00000000, 0x00000001, 0x00000003, 0x00000007, 372231200Smm 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, 373231200Smm 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 374231200Smm 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 375231200Smm 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 376231200Smm 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 377231200Smm 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 378231200Smm 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 379231200Smm 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF 380231200Smm}; 381231200Smm 382231200Smm/* 383231200Smm * Shift away used bits in the cache data and fill it up with following bits. 384231200Smm * Call this when cache buffer does not have enough bits you need. 385231200Smm * 386231200Smm * Returns 1 if the cache buffer is full. 387231200Smm * Returns 0 if the cache buffer is not full; input buffer is empty. 388231200Smm */ 389231200Smmstatic int 390231200Smmrar_br_fillup(struct archive_read *a, struct rar_br *br) 391231200Smm{ 392231200Smm struct rar *rar = (struct rar *)(a->format->data); 393231200Smm int n = CACHE_BITS - br->cache_avail; 394231200Smm 395231200Smm for (;;) { 396231200Smm switch (n >> 3) { 397231200Smm case 8: 398231200Smm if (br->avail_in >= 8) { 399231200Smm br->cache_buffer = 400231200Smm ((uint64_t)br->next_in[0]) << 56 | 401231200Smm ((uint64_t)br->next_in[1]) << 48 | 402231200Smm ((uint64_t)br->next_in[2]) << 40 | 403231200Smm ((uint64_t)br->next_in[3]) << 32 | 404231200Smm ((uint32_t)br->next_in[4]) << 24 | 405231200Smm ((uint32_t)br->next_in[5]) << 16 | 406231200Smm ((uint32_t)br->next_in[6]) << 8 | 407231200Smm (uint32_t)br->next_in[7]; 408231200Smm br->next_in += 8; 409231200Smm br->avail_in -= 8; 410231200Smm br->cache_avail += 8 * 8; 411231200Smm rar->bytes_unconsumed += 8; 412231200Smm rar->bytes_remaining -= 8; 413231200Smm return (1); 414231200Smm } 415231200Smm break; 416231200Smm case 7: 417231200Smm if (br->avail_in >= 7) { 418231200Smm br->cache_buffer = 419231200Smm (br->cache_buffer << 56) | 420231200Smm ((uint64_t)br->next_in[0]) << 48 | 421231200Smm ((uint64_t)br->next_in[1]) << 40 | 422231200Smm ((uint64_t)br->next_in[2]) << 32 | 423231200Smm ((uint32_t)br->next_in[3]) << 24 | 424231200Smm ((uint32_t)br->next_in[4]) << 16 | 425231200Smm ((uint32_t)br->next_in[5]) << 8 | 426231200Smm (uint32_t)br->next_in[6]; 427231200Smm br->next_in += 7; 428231200Smm br->avail_in -= 7; 429231200Smm br->cache_avail += 7 * 8; 430231200Smm rar->bytes_unconsumed += 7; 431231200Smm rar->bytes_remaining -= 7; 432231200Smm return (1); 433231200Smm } 434231200Smm break; 435231200Smm case 6: 436231200Smm if (br->avail_in >= 6) { 437231200Smm br->cache_buffer = 438231200Smm (br->cache_buffer << 48) | 439231200Smm ((uint64_t)br->next_in[0]) << 40 | 440231200Smm ((uint64_t)br->next_in[1]) << 32 | 441231200Smm ((uint32_t)br->next_in[2]) << 24 | 442231200Smm ((uint32_t)br->next_in[3]) << 16 | 443231200Smm ((uint32_t)br->next_in[4]) << 8 | 444231200Smm (uint32_t)br->next_in[5]; 445231200Smm br->next_in += 6; 446231200Smm br->avail_in -= 6; 447231200Smm br->cache_avail += 6 * 8; 448231200Smm rar->bytes_unconsumed += 6; 449231200Smm rar->bytes_remaining -= 6; 450231200Smm return (1); 451231200Smm } 452231200Smm break; 453231200Smm case 0: 454231200Smm /* We have enough compressed data in 455231200Smm * the cache buffer.*/ 456231200Smm return (1); 457231200Smm default: 458231200Smm break; 459231200Smm } 460231200Smm if (br->avail_in <= 0) { 461231200Smm 462231200Smm if (rar->bytes_unconsumed > 0) { 463231200Smm /* Consume as much as the decompressor 464231200Smm * actually used. */ 465231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 466231200Smm rar->bytes_unconsumed = 0; 467231200Smm } 468248616Smm br->next_in = rar_read_ahead(a, 1, &(br->avail_in)); 469231200Smm if (br->next_in == NULL) 470231200Smm return (0); 471231200Smm if (br->avail_in == 0) 472231200Smm return (0); 473231200Smm } 474231200Smm br->cache_buffer = 475231200Smm (br->cache_buffer << 8) | *br->next_in++; 476231200Smm br->avail_in--; 477231200Smm br->cache_avail += 8; 478231200Smm n -= 8; 479231200Smm rar->bytes_unconsumed++; 480231200Smm rar->bytes_remaining--; 481231200Smm } 482231200Smm} 483231200Smm 484231200Smmstatic int 485231200Smmrar_br_preparation(struct archive_read *a, struct rar_br *br) 486231200Smm{ 487231200Smm struct rar *rar = (struct rar *)(a->format->data); 488231200Smm 489231200Smm if (rar->bytes_remaining > 0) { 490248616Smm br->next_in = rar_read_ahead(a, 1, &(br->avail_in)); 491231200Smm if (br->next_in == NULL) { 492231200Smm archive_set_error(&a->archive, 493231200Smm ARCHIVE_ERRNO_FILE_FORMAT, 494231200Smm "Truncated RAR file data"); 495231200Smm return (ARCHIVE_FATAL); 496231200Smm } 497231200Smm if (br->cache_avail == 0) 498231200Smm (void)rar_br_fillup(a, br); 499231200Smm } 500231200Smm return (ARCHIVE_OK); 501231200Smm} 502231200Smm 503231200Smm/* Find last bit set */ 504231200Smmstatic inline int 505231200Smmrar_fls(unsigned int word) 506231200Smm{ 507231200Smm word |= (word >> 1); 508231200Smm word |= (word >> 2); 509231200Smm word |= (word >> 4); 510231200Smm word |= (word >> 8); 511231200Smm word |= (word >> 16); 512231200Smm return word - (word >> 1); 513231200Smm} 514231200Smm 515231200Smm/* LZSS functions */ 516231200Smmstatic inline int64_t 517231200Smmlzss_position(struct lzss *lzss) 518231200Smm{ 519231200Smm return lzss->position; 520231200Smm} 521231200Smm 522231200Smmstatic inline int 523231200Smmlzss_mask(struct lzss *lzss) 524231200Smm{ 525231200Smm return lzss->mask; 526231200Smm} 527231200Smm 528231200Smmstatic inline int 529231200Smmlzss_size(struct lzss *lzss) 530231200Smm{ 531231200Smm return lzss->mask + 1; 532231200Smm} 533231200Smm 534231200Smmstatic inline int 535231200Smmlzss_offset_for_position(struct lzss *lzss, int64_t pos) 536231200Smm{ 537238856Smm return (int)(pos & lzss->mask); 538231200Smm} 539231200Smm 540231200Smmstatic inline unsigned char * 541231200Smmlzss_pointer_for_position(struct lzss *lzss, int64_t pos) 542231200Smm{ 543231200Smm return &lzss->window[lzss_offset_for_position(lzss, pos)]; 544231200Smm} 545231200Smm 546231200Smmstatic inline int 547231200Smmlzss_current_offset(struct lzss *lzss) 548231200Smm{ 549231200Smm return lzss_offset_for_position(lzss, lzss->position); 550231200Smm} 551231200Smm 552231200Smmstatic inline uint8_t * 553231200Smmlzss_current_pointer(struct lzss *lzss) 554231200Smm{ 555231200Smm return lzss_pointer_for_position(lzss, lzss->position); 556231200Smm} 557231200Smm 558231200Smmstatic inline void 559231200Smmlzss_emit_literal(struct rar *rar, uint8_t literal) 560231200Smm{ 561231200Smm *lzss_current_pointer(&rar->lzss) = literal; 562231200Smm rar->lzss.position++; 563231200Smm} 564231200Smm 565231200Smmstatic inline void 566231200Smmlzss_emit_match(struct rar *rar, int offset, int length) 567231200Smm{ 568231200Smm int dstoffs = lzss_current_offset(&rar->lzss); 569231200Smm int srcoffs = (dstoffs - offset) & lzss_mask(&rar->lzss); 570231200Smm int l, li, remaining; 571231200Smm unsigned char *d, *s; 572231200Smm 573231200Smm remaining = length; 574231200Smm while (remaining > 0) { 575231200Smm l = remaining; 576231200Smm if (dstoffs > srcoffs) { 577231200Smm if (l > lzss_size(&rar->lzss) - dstoffs) 578231200Smm l = lzss_size(&rar->lzss) - dstoffs; 579231200Smm } else { 580231200Smm if (l > lzss_size(&rar->lzss) - srcoffs) 581231200Smm l = lzss_size(&rar->lzss) - srcoffs; 582231200Smm } 583231200Smm d = &(rar->lzss.window[dstoffs]); 584231200Smm s = &(rar->lzss.window[srcoffs]); 585231200Smm if ((dstoffs + l < srcoffs) || (srcoffs + l < dstoffs)) 586231200Smm memcpy(d, s, l); 587231200Smm else { 588231200Smm for (li = 0; li < l; li++) 589231200Smm d[li] = s[li]; 590231200Smm } 591231200Smm remaining -= l; 592231200Smm dstoffs = (dstoffs + l) & lzss_mask(&(rar->lzss)); 593231200Smm srcoffs = (srcoffs + l) & lzss_mask(&(rar->lzss)); 594231200Smm } 595231200Smm rar->lzss.position += length; 596231200Smm} 597231200Smm 598231200Smmstatic void * 599231200Smmppmd_alloc(void *p, size_t size) 600231200Smm{ 601231200Smm (void)p; 602231200Smm return malloc(size); 603231200Smm} 604231200Smmstatic void 605231200Smmppmd_free(void *p, void *address) 606231200Smm{ 607231200Smm (void)p; 608231200Smm free(address); 609231200Smm} 610231200Smmstatic ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free }; 611231200Smm 612231200Smmstatic Byte 613231200Smmppmd_read(void *p) 614231200Smm{ 615231200Smm struct archive_read *a = ((IByteIn*)p)->a; 616231200Smm struct rar *rar = (struct rar *)(a->format->data); 617231200Smm struct rar_br *br = &(rar->br); 618231200Smm Byte b; 619231200Smm if (!rar_br_read_ahead(a, br, 8)) 620231200Smm { 621231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 622231200Smm "Truncated RAR file data"); 623231200Smm rar->valid = 0; 624231200Smm return 0; 625231200Smm } 626231200Smm b = rar_br_bits(br, 8); 627231200Smm rar_br_consume(br, 8); 628231200Smm return b; 629231200Smm} 630231200Smm 631231200Smmint 632231200Smmarchive_read_support_format_rar(struct archive *_a) 633231200Smm{ 634231200Smm struct archive_read *a = (struct archive_read *)_a; 635231200Smm struct rar *rar; 636231200Smm int r; 637231200Smm 638231200Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 639231200Smm "archive_read_support_format_rar"); 640231200Smm 641231200Smm rar = (struct rar *)malloc(sizeof(*rar)); 642231200Smm if (rar == NULL) 643231200Smm { 644231200Smm archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data"); 645231200Smm return (ARCHIVE_FATAL); 646231200Smm } 647231200Smm memset(rar, 0, sizeof(*rar)); 648231200Smm 649231200Smm r = __archive_read_register_format(a, 650231200Smm rar, 651231200Smm "rar", 652231200Smm archive_read_format_rar_bid, 653231200Smm archive_read_format_rar_options, 654231200Smm archive_read_format_rar_read_header, 655231200Smm archive_read_format_rar_read_data, 656231200Smm archive_read_format_rar_read_data_skip, 657248616Smm archive_read_format_rar_seek_data, 658231200Smm archive_read_format_rar_cleanup); 659231200Smm 660231200Smm if (r != ARCHIVE_OK) 661231200Smm free(rar); 662231200Smm return (r); 663231200Smm} 664231200Smm 665231200Smmstatic int 666231200Smmarchive_read_format_rar_bid(struct archive_read *a, int best_bid) 667231200Smm{ 668231200Smm const char *p; 669231200Smm 670231200Smm /* If there's already a bid > 30, we'll never win. */ 671231200Smm if (best_bid > 30) 672231200Smm return (-1); 673231200Smm 674231200Smm if ((p = __archive_read_ahead(a, 7, NULL)) == NULL) 675231200Smm return (-1); 676231200Smm 677231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) 678231200Smm return (30); 679231200Smm 680231200Smm if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) { 681231200Smm /* This is a PE file */ 682231200Smm ssize_t offset = 0x10000; 683231200Smm ssize_t window = 4096; 684231200Smm ssize_t bytes_avail; 685231200Smm while (offset + window <= (1024 * 128)) { 686231200Smm const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail); 687231200Smm if (buff == NULL) { 688231200Smm /* Remaining bytes are less than window. */ 689231200Smm window >>= 1; 690231200Smm if (window < 0x40) 691231200Smm return (0); 692231200Smm continue; 693231200Smm } 694231200Smm p = buff + offset; 695231200Smm while (p + 7 < buff + bytes_avail) { 696231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) 697231200Smm return (30); 698231200Smm p += 0x10; 699231200Smm } 700231200Smm offset = p - buff; 701231200Smm } 702231200Smm } 703231200Smm return (0); 704231200Smm} 705231200Smm 706231200Smmstatic int 707231200Smmskip_sfx(struct archive_read *a) 708231200Smm{ 709231200Smm const void *h; 710231200Smm const char *p, *q; 711231200Smm size_t skip, total; 712231200Smm ssize_t bytes, window; 713231200Smm 714231200Smm total = 0; 715231200Smm window = 4096; 716231200Smm while (total + window <= (1024 * 128)) { 717231200Smm h = __archive_read_ahead(a, window, &bytes); 718231200Smm if (h == NULL) { 719231200Smm /* Remaining bytes are less than window. */ 720231200Smm window >>= 1; 721231200Smm if (window < 0x40) 722231200Smm goto fatal; 723231200Smm continue; 724231200Smm } 725231200Smm if (bytes < 0x40) 726231200Smm goto fatal; 727231200Smm p = h; 728231200Smm q = p + bytes; 729231200Smm 730231200Smm /* 731231200Smm * Scan ahead until we find something that looks 732231200Smm * like the RAR header. 733231200Smm */ 734231200Smm while (p + 7 < q) { 735231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) { 736231200Smm skip = p - (const char *)h; 737231200Smm __archive_read_consume(a, skip); 738231200Smm return (ARCHIVE_OK); 739231200Smm } 740231200Smm p += 0x10; 741231200Smm } 742231200Smm skip = p - (const char *)h; 743231200Smm __archive_read_consume(a, skip); 744231200Smm total += skip; 745231200Smm } 746231200Smmfatal: 747231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 748231200Smm "Couldn't find out RAR header"); 749231200Smm return (ARCHIVE_FATAL); 750231200Smm} 751231200Smm 752231200Smmstatic int 753231200Smmarchive_read_format_rar_options(struct archive_read *a, 754231200Smm const char *key, const char *val) 755231200Smm{ 756231200Smm struct rar *rar; 757231200Smm int ret = ARCHIVE_FAILED; 758231200Smm 759231200Smm rar = (struct rar *)(a->format->data); 760231200Smm if (strcmp(key, "hdrcharset") == 0) { 761231200Smm if (val == NULL || val[0] == 0) 762231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 763231200Smm "rar: hdrcharset option needs a character-set name"); 764231200Smm else { 765231200Smm rar->opt_sconv = 766231200Smm archive_string_conversion_from_charset( 767231200Smm &a->archive, val, 0); 768231200Smm if (rar->opt_sconv != NULL) 769231200Smm ret = ARCHIVE_OK; 770231200Smm else 771231200Smm ret = ARCHIVE_FATAL; 772231200Smm } 773232153Smm return (ret); 774232153Smm } 775232153Smm 776232153Smm /* Note: The "warn" return is just to inform the options 777232153Smm * supervisor that we didn't handle it. It will generate 778232153Smm * a suitable error if no one used this option. */ 779232153Smm return (ARCHIVE_WARN); 780231200Smm} 781231200Smm 782231200Smmstatic int 783231200Smmarchive_read_format_rar_read_header(struct archive_read *a, 784231200Smm struct archive_entry *entry) 785231200Smm{ 786231200Smm const void *h; 787231200Smm const char *p; 788231200Smm struct rar *rar; 789231200Smm size_t skip; 790231200Smm char head_type; 791231200Smm int ret; 792231200Smm unsigned flags; 793231200Smm 794231200Smm a->archive.archive_format = ARCHIVE_FORMAT_RAR; 795231200Smm if (a->archive.archive_format_name == NULL) 796231200Smm a->archive.archive_format_name = "RAR"; 797231200Smm 798231200Smm rar = (struct rar *)(a->format->data); 799231200Smm 800231200Smm /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if 801231200Smm * this fails. 802231200Smm */ 803231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 804231200Smm return (ARCHIVE_EOF); 805231200Smm 806231200Smm p = h; 807231200Smm if (rar->found_first_header == 0 && 808231200Smm ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) { 809231200Smm /* This is an executable ? Must be self-extracting... */ 810231200Smm ret = skip_sfx(a); 811231200Smm if (ret < ARCHIVE_WARN) 812231200Smm return (ret); 813231200Smm } 814231200Smm rar->found_first_header = 1; 815231200Smm 816231200Smm while (1) 817231200Smm { 818231200Smm unsigned long crc32_val; 819231200Smm 820231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 821231200Smm return (ARCHIVE_FATAL); 822231200Smm p = h; 823231200Smm 824231200Smm head_type = p[2]; 825231200Smm switch(head_type) 826231200Smm { 827231200Smm case MARK_HEAD: 828231200Smm if (memcmp(p, RAR_SIGNATURE, 7) != 0) { 829231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 830231200Smm "Invalid marker header"); 831231200Smm return (ARCHIVE_FATAL); 832231200Smm } 833231200Smm __archive_read_consume(a, 7); 834231200Smm break; 835231200Smm 836231200Smm case MAIN_HEAD: 837231200Smm rar->main_flags = archive_le16dec(p + 3); 838231200Smm skip = archive_le16dec(p + 5); 839231200Smm if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) { 840231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 841231200Smm "Invalid header size"); 842231200Smm return (ARCHIVE_FATAL); 843231200Smm } 844231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 845231200Smm return (ARCHIVE_FATAL); 846231200Smm p = h; 847231200Smm memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1)); 848231200Smm memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1), 849231200Smm sizeof(rar->reserved2)); 850231200Smm if (rar->main_flags & MHD_ENCRYPTVER) { 851231200Smm if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) { 852231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 853231200Smm "Invalid header size"); 854231200Smm return (ARCHIVE_FATAL); 855231200Smm } 856231200Smm rar->encryptver = *(p + 7 + sizeof(rar->reserved1) + 857231200Smm sizeof(rar->reserved2)); 858231200Smm } 859231200Smm 860231200Smm if (rar->main_flags & MHD_PASSWORD) 861231200Smm { 862231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 863231200Smm "RAR encryption support unavailable."); 864231200Smm return (ARCHIVE_FATAL); 865231200Smm } 866231200Smm 867248616Smm crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2); 868231200Smm if ((crc32_val & 0xffff) != archive_le16dec(p)) { 869231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 870231200Smm "Header CRC error"); 871231200Smm return (ARCHIVE_FATAL); 872231200Smm } 873231200Smm __archive_read_consume(a, skip); 874231200Smm break; 875231200Smm 876231200Smm case FILE_HEAD: 877231200Smm return read_header(a, entry, head_type); 878231200Smm 879231200Smm case COMM_HEAD: 880231200Smm case AV_HEAD: 881231200Smm case SUB_HEAD: 882231200Smm case PROTECT_HEAD: 883231200Smm case SIGN_HEAD: 884248616Smm case ENDARC_HEAD: 885231200Smm flags = archive_le16dec(p + 3); 886231200Smm skip = archive_le16dec(p + 5); 887231200Smm if (skip < 7) { 888231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 889231200Smm "Invalid header size"); 890231200Smm return (ARCHIVE_FATAL); 891231200Smm } 892231200Smm if (skip > 7) { 893231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 894231200Smm return (ARCHIVE_FATAL); 895231200Smm p = h; 896231200Smm } 897231200Smm if (flags & HD_ADD_SIZE_PRESENT) 898231200Smm { 899231200Smm if (skip < 7 + 4) { 900231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 901231200Smm "Invalid header size"); 902231200Smm return (ARCHIVE_FATAL); 903231200Smm } 904231200Smm skip += archive_le32dec(p + 7); 905231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 906231200Smm return (ARCHIVE_FATAL); 907231200Smm p = h; 908231200Smm } 909231200Smm 910248616Smm crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2); 911231200Smm if ((crc32_val & 0xffff) != archive_le16dec(p)) { 912231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 913231200Smm "Header CRC error"); 914231200Smm return (ARCHIVE_FATAL); 915231200Smm } 916231200Smm __archive_read_consume(a, skip); 917248616Smm if (head_type == ENDARC_HEAD) 918248616Smm return (ARCHIVE_EOF); 919231200Smm break; 920231200Smm 921231200Smm case NEWSUB_HEAD: 922231200Smm if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN) 923231200Smm return ret; 924231200Smm break; 925231200Smm 926231200Smm default: 927231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 928231200Smm "Bad RAR file"); 929231200Smm return (ARCHIVE_FATAL); 930231200Smm } 931231200Smm } 932231200Smm} 933231200Smm 934231200Smmstatic int 935231200Smmarchive_read_format_rar_read_data(struct archive_read *a, const void **buff, 936231200Smm size_t *size, int64_t *offset) 937231200Smm{ 938231200Smm struct rar *rar = (struct rar *)(a->format->data); 939231200Smm int ret; 940231200Smm 941231200Smm if (rar->bytes_unconsumed > 0) { 942231200Smm /* Consume as much as the decompressor actually used. */ 943231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 944231200Smm rar->bytes_unconsumed = 0; 945231200Smm } 946231200Smm 947248616Smm if (rar->entry_eof || rar->offset_seek >= rar->unp_size) { 948231200Smm *buff = NULL; 949231200Smm *size = 0; 950231200Smm *offset = rar->offset; 951248616Smm if (*offset < rar->unp_size) 952248616Smm *offset = rar->unp_size; 953231200Smm return (ARCHIVE_EOF); 954231200Smm } 955231200Smm 956231200Smm switch (rar->compression_method) 957231200Smm { 958231200Smm case COMPRESS_METHOD_STORE: 959231200Smm ret = read_data_stored(a, buff, size, offset); 960231200Smm break; 961231200Smm 962231200Smm case COMPRESS_METHOD_FASTEST: 963231200Smm case COMPRESS_METHOD_FAST: 964231200Smm case COMPRESS_METHOD_NORMAL: 965231200Smm case COMPRESS_METHOD_GOOD: 966231200Smm case COMPRESS_METHOD_BEST: 967231200Smm ret = read_data_compressed(a, buff, size, offset); 968231200Smm if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) 969231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 970231200Smm break; 971231200Smm 972231200Smm default: 973231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 974231200Smm "Unsupported compression method for RAR file."); 975231200Smm ret = ARCHIVE_FATAL; 976231200Smm break; 977231200Smm } 978231200Smm return (ret); 979231200Smm} 980231200Smm 981231200Smmstatic int 982231200Smmarchive_read_format_rar_read_data_skip(struct archive_read *a) 983231200Smm{ 984231200Smm struct rar *rar; 985231200Smm int64_t bytes_skipped; 986248616Smm int ret; 987231200Smm 988231200Smm rar = (struct rar *)(a->format->data); 989231200Smm 990231200Smm if (rar->bytes_unconsumed > 0) { 991231200Smm /* Consume as much as the decompressor actually used. */ 992231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 993231200Smm rar->bytes_unconsumed = 0; 994231200Smm } 995231200Smm 996231200Smm if (rar->bytes_remaining > 0) { 997231200Smm bytes_skipped = __archive_read_consume(a, rar->bytes_remaining); 998231200Smm if (bytes_skipped < 0) 999231200Smm return (ARCHIVE_FATAL); 1000231200Smm } 1001248616Smm 1002248616Smm /* Compressed data to skip must be read from each header in a multivolume 1003248616Smm * archive. 1004248616Smm */ 1005248616Smm if (rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER) 1006248616Smm { 1007248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1008248616Smm if (ret == (ARCHIVE_EOF)) 1009248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1010248616Smm if (ret != (ARCHIVE_OK)) 1011248616Smm return ret; 1012248616Smm return archive_read_format_rar_read_data_skip(a); 1013248616Smm } 1014248616Smm 1015231200Smm return (ARCHIVE_OK); 1016231200Smm} 1017231200Smm 1018248616Smmstatic int64_t 1019248616Smmarchive_read_format_rar_seek_data(struct archive_read *a, int64_t offset, 1020248616Smm int whence) 1021248616Smm{ 1022248616Smm int64_t client_offset, ret; 1023248616Smm unsigned int i; 1024248616Smm struct rar *rar = (struct rar *)(a->format->data); 1025248616Smm 1026248616Smm if (rar->compression_method == COMPRESS_METHOD_STORE) 1027248616Smm { 1028248616Smm /* Modify the offset for use with SEEK_SET */ 1029248616Smm switch (whence) 1030248616Smm { 1031248616Smm case SEEK_CUR: 1032248616Smm client_offset = rar->offset_seek; 1033248616Smm break; 1034248616Smm case SEEK_END: 1035248616Smm client_offset = rar->unp_size; 1036248616Smm break; 1037248616Smm case SEEK_SET: 1038248616Smm default: 1039248616Smm client_offset = 0; 1040248616Smm } 1041248616Smm client_offset += offset; 1042248616Smm if (client_offset < 0) 1043248616Smm { 1044248616Smm /* Can't seek past beginning of data block */ 1045248616Smm return -1; 1046248616Smm } 1047248616Smm else if (client_offset > rar->unp_size) 1048248616Smm { 1049248616Smm /* 1050248616Smm * Set the returned offset but only seek to the end of 1051248616Smm * the data block. 1052248616Smm */ 1053248616Smm rar->offset_seek = client_offset; 1054248616Smm client_offset = rar->unp_size; 1055248616Smm } 1056248616Smm 1057248616Smm client_offset += rar->dbo[0].start_offset; 1058248616Smm i = 0; 1059248616Smm while (i < rar->cursor) 1060248616Smm { 1061248616Smm i++; 1062248616Smm client_offset += rar->dbo[i].start_offset - rar->dbo[i-1].end_offset; 1063248616Smm } 1064248616Smm if (rar->main_flags & MHD_VOLUME) 1065248616Smm { 1066248616Smm /* Find the appropriate offset among the multivolume archive */ 1067248616Smm while (1) 1068248616Smm { 1069248616Smm if (client_offset < rar->dbo[rar->cursor].start_offset && 1070248616Smm rar->file_flags & FHD_SPLIT_BEFORE) 1071248616Smm { 1072248616Smm /* Search backwards for the correct data block */ 1073248616Smm if (rar->cursor == 0) 1074248616Smm { 1075248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1076248616Smm "Attempt to seek past beginning of RAR data block"); 1077248616Smm return (ARCHIVE_FAILED); 1078248616Smm } 1079248616Smm rar->cursor--; 1080248616Smm client_offset -= rar->dbo[rar->cursor+1].start_offset - 1081248616Smm rar->dbo[rar->cursor].end_offset; 1082248616Smm if (client_offset < rar->dbo[rar->cursor].start_offset) 1083248616Smm continue; 1084248616Smm ret = __archive_read_seek(a, rar->dbo[rar->cursor].start_offset - 1085248616Smm rar->dbo[rar->cursor].header_size, SEEK_SET); 1086248616Smm if (ret < (ARCHIVE_OK)) 1087248616Smm return ret; 1088248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1089248616Smm if (ret != (ARCHIVE_OK)) 1090248616Smm { 1091248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1092248616Smm "Error during seek of RAR file"); 1093248616Smm return (ARCHIVE_FAILED); 1094248616Smm } 1095248616Smm rar->cursor--; 1096248616Smm break; 1097248616Smm } 1098248616Smm else if (client_offset > rar->dbo[rar->cursor].end_offset && 1099248616Smm rar->file_flags & FHD_SPLIT_AFTER) 1100248616Smm { 1101248616Smm /* Search forward for the correct data block */ 1102248616Smm rar->cursor++; 1103248616Smm if (rar->cursor < rar->nodes && 1104248616Smm client_offset > rar->dbo[rar->cursor].end_offset) 1105248616Smm { 1106248616Smm client_offset += rar->dbo[rar->cursor].start_offset - 1107248616Smm rar->dbo[rar->cursor-1].end_offset; 1108248616Smm continue; 1109248616Smm } 1110248616Smm rar->cursor--; 1111248616Smm ret = __archive_read_seek(a, rar->dbo[rar->cursor].end_offset, 1112248616Smm SEEK_SET); 1113248616Smm if (ret < (ARCHIVE_OK)) 1114248616Smm return ret; 1115248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1116248616Smm if (ret == (ARCHIVE_EOF)) 1117248616Smm { 1118248616Smm rar->has_endarc_header = 1; 1119248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1120248616Smm } 1121248616Smm if (ret != (ARCHIVE_OK)) 1122248616Smm { 1123248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1124248616Smm "Error during seek of RAR file"); 1125248616Smm return (ARCHIVE_FAILED); 1126248616Smm } 1127248616Smm client_offset += rar->dbo[rar->cursor].start_offset - 1128248616Smm rar->dbo[rar->cursor-1].end_offset; 1129248616Smm continue; 1130248616Smm } 1131248616Smm break; 1132248616Smm } 1133248616Smm } 1134248616Smm 1135248616Smm ret = __archive_read_seek(a, client_offset, SEEK_SET); 1136248616Smm if (ret < (ARCHIVE_OK)) 1137248616Smm return ret; 1138248616Smm rar->bytes_remaining = rar->dbo[rar->cursor].end_offset - ret; 1139248616Smm i = rar->cursor; 1140248616Smm while (i > 0) 1141248616Smm { 1142248616Smm i--; 1143248616Smm ret -= rar->dbo[i+1].start_offset - rar->dbo[i].end_offset; 1144248616Smm } 1145248616Smm ret -= rar->dbo[0].start_offset; 1146248616Smm 1147248616Smm /* Always restart reading the file after a seek */ 1148248616Smm a->read_data_block = NULL; 1149248616Smm a->read_data_offset = 0; 1150248616Smm a->read_data_output_offset = 0; 1151248616Smm a->read_data_remaining = 0; 1152248616Smm rar->bytes_unconsumed = 0; 1153248616Smm rar->offset = 0; 1154248616Smm 1155248616Smm /* 1156248616Smm * If a seek past the end of file was requested, return the requested 1157248616Smm * offset. 1158248616Smm */ 1159248616Smm if (ret == rar->unp_size && rar->offset_seek > rar->unp_size) 1160248616Smm return rar->offset_seek; 1161248616Smm 1162248616Smm /* Return the new offset */ 1163248616Smm rar->offset_seek = ret; 1164248616Smm return rar->offset_seek; 1165248616Smm } 1166248616Smm else 1167248616Smm { 1168248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1169248616Smm "Seeking of compressed RAR files is unsupported"); 1170248616Smm } 1171248616Smm return (ARCHIVE_FAILED); 1172248616Smm} 1173248616Smm 1174231200Smmstatic int 1175231200Smmarchive_read_format_rar_cleanup(struct archive_read *a) 1176231200Smm{ 1177231200Smm struct rar *rar; 1178231200Smm 1179231200Smm rar = (struct rar *)(a->format->data); 1180231200Smm free_codes(a); 1181231200Smm free(rar->filename); 1182248616Smm free(rar->filename_save); 1183248616Smm free(rar->dbo); 1184231200Smm free(rar->unp_buffer); 1185231200Smm free(rar->lzss.window); 1186231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 1187231200Smm free(rar); 1188231200Smm (a->format->data) = NULL; 1189231200Smm return (ARCHIVE_OK); 1190231200Smm} 1191231200Smm 1192231200Smmstatic int 1193231200Smmread_header(struct archive_read *a, struct archive_entry *entry, 1194231200Smm char head_type) 1195231200Smm{ 1196231200Smm const void *h; 1197231200Smm const char *p, *endp; 1198231200Smm struct rar *rar; 1199231200Smm struct rar_header rar_header; 1200231200Smm struct rar_file_header file_header; 1201231200Smm int64_t header_size; 1202231200Smm unsigned filename_size, end; 1203231200Smm char *filename; 1204231200Smm char *strp; 1205231200Smm char packed_size[8]; 1206231200Smm char unp_size[8]; 1207232153Smm int ttime; 1208231200Smm struct archive_string_conv *sconv, *fn_sconv; 1209231200Smm unsigned long crc32_val; 1210231200Smm int ret = (ARCHIVE_OK), ret2; 1211231200Smm 1212231200Smm rar = (struct rar *)(a->format->data); 1213231200Smm 1214231200Smm /* Setup a string conversion object for non-rar-unicode filenames. */ 1215231200Smm sconv = rar->opt_sconv; 1216231200Smm if (sconv == NULL) { 1217231200Smm if (!rar->init_default_conversion) { 1218231200Smm rar->sconv_default = 1219231200Smm archive_string_default_conversion_for_read( 1220231200Smm &(a->archive)); 1221231200Smm rar->init_default_conversion = 1; 1222231200Smm } 1223231200Smm sconv = rar->sconv_default; 1224231200Smm } 1225231200Smm 1226231200Smm 1227231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 1228231200Smm return (ARCHIVE_FATAL); 1229231200Smm p = h; 1230231200Smm memcpy(&rar_header, p, sizeof(rar_header)); 1231231200Smm rar->file_flags = archive_le16dec(rar_header.flags); 1232231200Smm header_size = archive_le16dec(rar_header.size); 1233232153Smm if (header_size < (int64_t)sizeof(file_header) + 7) { 1234231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1235231200Smm "Invalid header size"); 1236231200Smm return (ARCHIVE_FATAL); 1237231200Smm } 1238231200Smm crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2); 1239231200Smm __archive_read_consume(a, 7); 1240231200Smm 1241231200Smm if (!(rar->file_flags & FHD_SOLID)) 1242231200Smm { 1243231200Smm rar->compression_method = 0; 1244231200Smm rar->packed_size = 0; 1245231200Smm rar->unp_size = 0; 1246231200Smm rar->mtime = 0; 1247231200Smm rar->ctime = 0; 1248231200Smm rar->atime = 0; 1249231200Smm rar->arctime = 0; 1250231200Smm rar->mode = 0; 1251231200Smm memset(&rar->salt, 0, sizeof(rar->salt)); 1252231200Smm rar->atime = 0; 1253231200Smm rar->ansec = 0; 1254231200Smm rar->ctime = 0; 1255231200Smm rar->cnsec = 0; 1256231200Smm rar->mtime = 0; 1257231200Smm rar->mnsec = 0; 1258231200Smm rar->arctime = 0; 1259231200Smm rar->arcnsec = 0; 1260231200Smm } 1261231200Smm else 1262231200Smm { 1263231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1264231200Smm "RAR solid archive support unavailable."); 1265231200Smm return (ARCHIVE_FATAL); 1266231200Smm } 1267231200Smm 1268238856Smm if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL) 1269231200Smm return (ARCHIVE_FATAL); 1270231200Smm 1271231200Smm /* File Header CRC check. */ 1272238856Smm crc32_val = crc32(crc32_val, h, (unsigned)(header_size - 7)); 1273231200Smm if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) { 1274231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1275231200Smm "Header CRC error"); 1276231200Smm return (ARCHIVE_FATAL); 1277231200Smm } 1278231200Smm /* If no CRC error, Go on parsing File Header. */ 1279231200Smm p = h; 1280231200Smm endp = p + header_size - 7; 1281231200Smm memcpy(&file_header, p, sizeof(file_header)); 1282231200Smm p += sizeof(file_header); 1283231200Smm 1284231200Smm rar->compression_method = file_header.method; 1285231200Smm 1286232153Smm ttime = archive_le32dec(file_header.file_time); 1287232153Smm rar->mtime = get_time(ttime); 1288231200Smm 1289231200Smm rar->file_crc = archive_le32dec(file_header.file_crc); 1290231200Smm 1291231200Smm if (rar->file_flags & FHD_PASSWORD) 1292231200Smm { 1293231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1294231200Smm "RAR encryption support unavailable."); 1295231200Smm return (ARCHIVE_FATAL); 1296231200Smm } 1297231200Smm 1298231200Smm if (rar->file_flags & FHD_LARGE) 1299231200Smm { 1300231200Smm memcpy(packed_size, file_header.pack_size, 4); 1301231200Smm memcpy(packed_size + 4, p, 4); /* High pack size */ 1302231200Smm p += 4; 1303231200Smm memcpy(unp_size, file_header.unp_size, 4); 1304231200Smm memcpy(unp_size + 4, p, 4); /* High unpack size */ 1305231200Smm p += 4; 1306231200Smm rar->packed_size = archive_le64dec(&packed_size); 1307231200Smm rar->unp_size = archive_le64dec(&unp_size); 1308231200Smm } 1309231200Smm else 1310231200Smm { 1311231200Smm rar->packed_size = archive_le32dec(file_header.pack_size); 1312231200Smm rar->unp_size = archive_le32dec(file_header.unp_size); 1313231200Smm } 1314231200Smm 1315231200Smm if (rar->packed_size < 0 || rar->unp_size < 0) 1316231200Smm { 1317231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1318231200Smm "Invalid sizes specified."); 1319231200Smm return (ARCHIVE_FATAL); 1320231200Smm } 1321231200Smm 1322248616Smm rar->bytes_remaining = rar->packed_size; 1323248616Smm 1324231200Smm /* TODO: RARv3 subblocks contain comments. For now the complete block is 1325231200Smm * consumed at the end. 1326231200Smm */ 1327231200Smm if (head_type == NEWSUB_HEAD) { 1328231200Smm size_t distance = p - (const char *)h; 1329231200Smm header_size += rar->packed_size; 1330231200Smm /* Make sure we have the extended data. */ 1331238856Smm if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL) 1332231200Smm return (ARCHIVE_FATAL); 1333231200Smm p = h; 1334231200Smm endp = p + header_size - 7; 1335231200Smm p += distance; 1336231200Smm } 1337231200Smm 1338231200Smm filename_size = archive_le16dec(file_header.name_size); 1339231200Smm if (p + filename_size > endp) { 1340231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1341231200Smm "Invalid filename size"); 1342231200Smm return (ARCHIVE_FATAL); 1343231200Smm } 1344238856Smm if (rar->filename_allocated < filename_size * 2 + 2) { 1345238856Smm char *newptr; 1346238856Smm size_t newsize = filename_size * 2 + 2; 1347238856Smm newptr = realloc(rar->filename, newsize); 1348238856Smm if (newptr == NULL) { 1349231200Smm archive_set_error(&a->archive, ENOMEM, 1350231200Smm "Couldn't allocate memory."); 1351231200Smm return (ARCHIVE_FATAL); 1352231200Smm } 1353238856Smm rar->filename = newptr; 1354238856Smm rar->filename_allocated = newsize; 1355231200Smm } 1356231200Smm filename = rar->filename; 1357231200Smm memcpy(filename, p, filename_size); 1358231200Smm filename[filename_size] = '\0'; 1359231200Smm if (rar->file_flags & FHD_UNICODE) 1360231200Smm { 1361231200Smm if (filename_size != strlen(filename)) 1362231200Smm { 1363248616Smm unsigned char highbyte, flagbits, flagbyte; 1364248616Smm unsigned fn_end, offset; 1365231200Smm 1366231200Smm end = filename_size; 1367238856Smm fn_end = filename_size * 2; 1368231200Smm filename_size = 0; 1369248616Smm offset = (unsigned)strlen(filename) + 1; 1370231200Smm highbyte = *(p + offset++); 1371231200Smm flagbits = 0; 1372231200Smm flagbyte = 0; 1373238856Smm while (offset < end && filename_size < fn_end) 1374231200Smm { 1375231200Smm if (!flagbits) 1376231200Smm { 1377231200Smm flagbyte = *(p + offset++); 1378231200Smm flagbits = 8; 1379231200Smm } 1380231200Smm 1381231200Smm flagbits -= 2; 1382231200Smm switch((flagbyte >> flagbits) & 3) 1383231200Smm { 1384231200Smm case 0: 1385231200Smm filename[filename_size++] = '\0'; 1386231200Smm filename[filename_size++] = *(p + offset++); 1387231200Smm break; 1388231200Smm case 1: 1389231200Smm filename[filename_size++] = highbyte; 1390231200Smm filename[filename_size++] = *(p + offset++); 1391231200Smm break; 1392231200Smm case 2: 1393231200Smm filename[filename_size++] = *(p + offset + 1); 1394231200Smm filename[filename_size++] = *(p + offset); 1395231200Smm offset += 2; 1396231200Smm break; 1397231200Smm case 3: 1398231200Smm { 1399238856Smm char extra, high; 1400238856Smm uint8_t length = *(p + offset++); 1401238856Smm 1402238856Smm if (length & 0x80) { 1403238856Smm extra = *(p + offset++); 1404238856Smm high = (char)highbyte; 1405238856Smm } else 1406238856Smm extra = high = 0; 1407238856Smm length = (length & 0x7f) + 2; 1408238856Smm while (length && filename_size < fn_end) { 1409238856Smm unsigned cp = filename_size >> 1; 1410238856Smm filename[filename_size++] = high; 1411238856Smm filename[filename_size++] = p[cp] + extra; 1412231200Smm length--; 1413231200Smm } 1414231200Smm } 1415231200Smm break; 1416231200Smm } 1417231200Smm } 1418238856Smm if (filename_size > fn_end) { 1419231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1420231200Smm "Invalid filename"); 1421231200Smm return (ARCHIVE_FATAL); 1422231200Smm } 1423231200Smm filename[filename_size++] = '\0'; 1424231200Smm filename[filename_size++] = '\0'; 1425231200Smm 1426231200Smm /* Decoded unicode form is UTF-16BE, so we have to update a string 1427231200Smm * conversion object for it. */ 1428231200Smm if (rar->sconv_utf16be == NULL) { 1429231200Smm rar->sconv_utf16be = archive_string_conversion_from_charset( 1430231200Smm &a->archive, "UTF-16BE", 1); 1431231200Smm if (rar->sconv_utf16be == NULL) 1432231200Smm return (ARCHIVE_FATAL); 1433231200Smm } 1434231200Smm fn_sconv = rar->sconv_utf16be; 1435231200Smm 1436231200Smm strp = filename; 1437231200Smm while (memcmp(strp, "\x00\x00", 2)) 1438231200Smm { 1439231200Smm if (!memcmp(strp, "\x00\\", 2)) 1440231200Smm *(strp + 1) = '/'; 1441231200Smm strp += 2; 1442231200Smm } 1443231200Smm p += offset; 1444231200Smm } else { 1445231200Smm /* 1446231200Smm * If FHD_UNICODE is set but no unicode data, this file name form 1447231200Smm * is UTF-8, so we have to update a string conversion object for 1448231200Smm * it accordingly. 1449231200Smm */ 1450231200Smm if (rar->sconv_utf8 == NULL) { 1451231200Smm rar->sconv_utf8 = archive_string_conversion_from_charset( 1452231200Smm &a->archive, "UTF-8", 1); 1453231200Smm if (rar->sconv_utf8 == NULL) 1454231200Smm return (ARCHIVE_FATAL); 1455231200Smm } 1456231200Smm fn_sconv = rar->sconv_utf8; 1457231200Smm while ((strp = strchr(filename, '\\')) != NULL) 1458231200Smm *strp = '/'; 1459231200Smm p += filename_size; 1460231200Smm } 1461231200Smm } 1462231200Smm else 1463231200Smm { 1464231200Smm fn_sconv = sconv; 1465231200Smm while ((strp = strchr(filename, '\\')) != NULL) 1466231200Smm *strp = '/'; 1467231200Smm p += filename_size; 1468231200Smm } 1469231200Smm 1470248616Smm /* Split file in multivolume RAR. No more need to process header. */ 1471248616Smm if (rar->filename_save && 1472248616Smm !memcmp(rar->filename, rar->filename_save, filename_size + 1)) 1473248616Smm { 1474248616Smm __archive_read_consume(a, header_size - 7); 1475248616Smm rar->cursor++; 1476248616Smm if (rar->cursor >= rar->nodes) 1477248616Smm { 1478248616Smm rar->nodes++; 1479248616Smm if ((rar->dbo = 1480248616Smm realloc(rar->dbo, sizeof(*rar->dbo) * rar->nodes)) == NULL) 1481248616Smm { 1482248616Smm archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory."); 1483248616Smm return (ARCHIVE_FATAL); 1484248616Smm } 1485248616Smm rar->dbo[rar->cursor].header_size = header_size; 1486248616Smm rar->dbo[rar->cursor].start_offset = -1; 1487248616Smm rar->dbo[rar->cursor].end_offset = -1; 1488248616Smm } 1489248616Smm if (rar->dbo[rar->cursor].start_offset < 0) 1490248616Smm { 1491248616Smm rar->dbo[rar->cursor].start_offset = a->filter->position; 1492248616Smm rar->dbo[rar->cursor].end_offset = rar->dbo[rar->cursor].start_offset + 1493248616Smm rar->packed_size; 1494248616Smm } 1495248616Smm return ret; 1496248616Smm } 1497248616Smm 1498248616Smm rar->filename_save = (char*)realloc(rar->filename_save, 1499248616Smm filename_size + 1); 1500248616Smm memcpy(rar->filename_save, rar->filename, filename_size + 1); 1501248616Smm 1502248616Smm /* Set info for seeking */ 1503248616Smm free(rar->dbo); 1504248616Smm if ((rar->dbo = calloc(1, sizeof(*rar->dbo))) == NULL) 1505248616Smm { 1506248616Smm archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory."); 1507248616Smm return (ARCHIVE_FATAL); 1508248616Smm } 1509248616Smm rar->dbo[0].header_size = header_size; 1510248616Smm rar->dbo[0].start_offset = -1; 1511248616Smm rar->dbo[0].end_offset = -1; 1512248616Smm rar->cursor = 0; 1513248616Smm rar->nodes = 1; 1514248616Smm 1515231200Smm if (rar->file_flags & FHD_SALT) 1516231200Smm { 1517231200Smm if (p + 8 > endp) { 1518231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1519231200Smm "Invalid header size"); 1520231200Smm return (ARCHIVE_FATAL); 1521231200Smm } 1522231200Smm memcpy(rar->salt, p, 8); 1523231200Smm p += 8; 1524231200Smm } 1525231200Smm 1526231200Smm if (rar->file_flags & FHD_EXTTIME) { 1527231200Smm if (read_exttime(p, rar, endp) < 0) { 1528231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1529231200Smm "Invalid header size"); 1530231200Smm return (ARCHIVE_FATAL); 1531231200Smm } 1532231200Smm } 1533231200Smm 1534231200Smm __archive_read_consume(a, header_size - 7); 1535248616Smm rar->dbo[0].start_offset = a->filter->position; 1536248616Smm rar->dbo[0].end_offset = rar->dbo[0].start_offset + rar->packed_size; 1537231200Smm 1538231200Smm switch(file_header.host_os) 1539231200Smm { 1540231200Smm case OS_MSDOS: 1541231200Smm case OS_OS2: 1542231200Smm case OS_WIN32: 1543231200Smm rar->mode = archive_le32dec(file_header.file_attr); 1544231200Smm if (rar->mode & FILE_ATTRIBUTE_DIRECTORY) 1545231200Smm rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; 1546231200Smm else 1547231200Smm rar->mode = AE_IFREG; 1548231200Smm rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 1549231200Smm break; 1550231200Smm 1551231200Smm case OS_UNIX: 1552231200Smm case OS_MAC_OS: 1553231200Smm case OS_BEOS: 1554231200Smm rar->mode = archive_le32dec(file_header.file_attr); 1555231200Smm break; 1556231200Smm 1557231200Smm default: 1558231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1559231200Smm "Unknown file attributes from RAR file's host OS"); 1560231200Smm return (ARCHIVE_FATAL); 1561231200Smm } 1562231200Smm 1563231200Smm rar->bytes_uncopied = rar->bytes_unconsumed = 0; 1564238856Smm rar->lzss.position = rar->offset = 0; 1565248616Smm rar->offset_seek = 0; 1566238856Smm rar->dictionary_size = 0; 1567231200Smm rar->offset_outgoing = 0; 1568231200Smm rar->br.cache_avail = 0; 1569231200Smm rar->br.avail_in = 0; 1570231200Smm rar->crc_calculated = 0; 1571231200Smm rar->entry_eof = 0; 1572231200Smm rar->valid = 1; 1573231200Smm rar->is_ppmd_block = 0; 1574231200Smm rar->start_new_table = 1; 1575231200Smm free(rar->unp_buffer); 1576231200Smm rar->unp_buffer = NULL; 1577231200Smm rar->unp_offset = 0; 1578231200Smm rar->unp_buffer_size = UNP_BUFFER_SIZE; 1579231200Smm memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); 1580231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 1581231200Smm rar->ppmd_valid = rar->ppmd_eod = 0; 1582231200Smm 1583231200Smm /* Don't set any archive entries for non-file header types */ 1584231200Smm if (head_type == NEWSUB_HEAD) 1585231200Smm return ret; 1586231200Smm 1587231200Smm archive_entry_set_mtime(entry, rar->mtime, rar->mnsec); 1588231200Smm archive_entry_set_ctime(entry, rar->ctime, rar->cnsec); 1589231200Smm archive_entry_set_atime(entry, rar->atime, rar->ansec); 1590231200Smm archive_entry_set_size(entry, rar->unp_size); 1591231200Smm archive_entry_set_mode(entry, rar->mode); 1592231200Smm 1593231200Smm if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv)) 1594231200Smm { 1595231200Smm if (errno == ENOMEM) 1596231200Smm { 1597231200Smm archive_set_error(&a->archive, ENOMEM, 1598231200Smm "Can't allocate memory for Pathname"); 1599231200Smm return (ARCHIVE_FATAL); 1600231200Smm } 1601231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1602231200Smm "Pathname cannot be converted from %s to current locale.", 1603231200Smm archive_string_conversion_charset_name(fn_sconv)); 1604231200Smm ret = (ARCHIVE_WARN); 1605231200Smm } 1606231200Smm 1607231200Smm if (((rar->mode) & AE_IFMT) == AE_IFLNK) 1608231200Smm { 1609231200Smm /* Make sure a symbolic-link file does not have its body. */ 1610231200Smm rar->bytes_remaining = 0; 1611231200Smm archive_entry_set_size(entry, 0); 1612231200Smm 1613231200Smm /* Read a symbolic-link name. */ 1614231200Smm if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN)) 1615231200Smm return ret2; 1616231200Smm if (ret > ret2) 1617231200Smm ret = ret2; 1618231200Smm } 1619231200Smm 1620231200Smm if (rar->bytes_remaining == 0) 1621231200Smm rar->entry_eof = 1; 1622231200Smm 1623231200Smm return ret; 1624231200Smm} 1625231200Smm 1626231200Smmstatic time_t 1627232153Smmget_time(int ttime) 1628231200Smm{ 1629231200Smm struct tm tm; 1630232153Smm tm.tm_sec = 2 * (ttime & 0x1f); 1631232153Smm tm.tm_min = (ttime >> 5) & 0x3f; 1632232153Smm tm.tm_hour = (ttime >> 11) & 0x1f; 1633232153Smm tm.tm_mday = (ttime >> 16) & 0x1f; 1634232153Smm tm.tm_mon = ((ttime >> 21) & 0x0f) - 1; 1635232153Smm tm.tm_year = ((ttime >> 25) & 0x7f) + 80; 1636231200Smm tm.tm_isdst = -1; 1637231200Smm return mktime(&tm); 1638231200Smm} 1639231200Smm 1640231200Smmstatic int 1641231200Smmread_exttime(const char *p, struct rar *rar, const char *endp) 1642231200Smm{ 1643231200Smm unsigned rmode, flags, rem, j, count; 1644232153Smm int ttime, i; 1645231200Smm struct tm *tm; 1646231200Smm time_t t; 1647231200Smm long nsec; 1648231200Smm 1649231200Smm if (p + 2 > endp) 1650231200Smm return (-1); 1651231200Smm flags = archive_le16dec(p); 1652231200Smm p += 2; 1653231200Smm 1654231200Smm for (i = 3; i >= 0; i--) 1655231200Smm { 1656231200Smm t = 0; 1657231200Smm if (i == 3) 1658231200Smm t = rar->mtime; 1659231200Smm rmode = flags >> i * 4; 1660231200Smm if (rmode & 8) 1661231200Smm { 1662231200Smm if (!t) 1663231200Smm { 1664231200Smm if (p + 4 > endp) 1665231200Smm return (-1); 1666232153Smm ttime = archive_le32dec(p); 1667232153Smm t = get_time(ttime); 1668231200Smm p += 4; 1669231200Smm } 1670231200Smm rem = 0; 1671231200Smm count = rmode & 3; 1672231200Smm if (p + count > endp) 1673231200Smm return (-1); 1674231200Smm for (j = 0; j < count; j++) 1675231200Smm { 1676231200Smm rem = ((*p) << 16) | (rem >> 8); 1677231200Smm p++; 1678231200Smm } 1679231200Smm tm = localtime(&t); 1680231200Smm nsec = tm->tm_sec + rem / NS_UNIT; 1681231200Smm if (rmode & 4) 1682231200Smm { 1683231200Smm tm->tm_sec++; 1684231200Smm t = mktime(tm); 1685231200Smm } 1686231200Smm if (i == 3) 1687231200Smm { 1688231200Smm rar->mtime = t; 1689231200Smm rar->mnsec = nsec; 1690231200Smm } 1691231200Smm else if (i == 2) 1692231200Smm { 1693231200Smm rar->ctime = t; 1694231200Smm rar->cnsec = nsec; 1695231200Smm } 1696231200Smm else if (i == 1) 1697231200Smm { 1698231200Smm rar->atime = t; 1699231200Smm rar->ansec = nsec; 1700231200Smm } 1701231200Smm else 1702231200Smm { 1703231200Smm rar->arctime = t; 1704231200Smm rar->arcnsec = nsec; 1705231200Smm } 1706231200Smm } 1707231200Smm } 1708231200Smm return (0); 1709231200Smm} 1710231200Smm 1711231200Smmstatic int 1712231200Smmread_symlink_stored(struct archive_read *a, struct archive_entry *entry, 1713231200Smm struct archive_string_conv *sconv) 1714231200Smm{ 1715231200Smm const void *h; 1716231200Smm const char *p; 1717231200Smm struct rar *rar; 1718231200Smm int ret = (ARCHIVE_OK); 1719231200Smm 1720231200Smm rar = (struct rar *)(a->format->data); 1721248616Smm if ((h = rar_read_ahead(a, (size_t)rar->packed_size, NULL)) == NULL) 1722231200Smm return (ARCHIVE_FATAL); 1723231200Smm p = h; 1724231200Smm 1725238856Smm if (archive_entry_copy_symlink_l(entry, 1726238856Smm p, (size_t)rar->packed_size, sconv)) 1727231200Smm { 1728231200Smm if (errno == ENOMEM) 1729231200Smm { 1730231200Smm archive_set_error(&a->archive, ENOMEM, 1731231200Smm "Can't allocate memory for link"); 1732231200Smm return (ARCHIVE_FATAL); 1733231200Smm } 1734231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1735231200Smm "link cannot be converted from %s to current locale.", 1736231200Smm archive_string_conversion_charset_name(sconv)); 1737231200Smm ret = (ARCHIVE_WARN); 1738231200Smm } 1739231200Smm __archive_read_consume(a, rar->packed_size); 1740231200Smm return ret; 1741231200Smm} 1742231200Smm 1743231200Smmstatic int 1744231200Smmread_data_stored(struct archive_read *a, const void **buff, size_t *size, 1745231200Smm int64_t *offset) 1746231200Smm{ 1747231200Smm struct rar *rar; 1748231200Smm ssize_t bytes_avail; 1749231200Smm 1750231200Smm rar = (struct rar *)(a->format->data); 1751248616Smm if (rar->bytes_remaining == 0 && 1752248616Smm !(rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER)) 1753231200Smm { 1754231200Smm *buff = NULL; 1755231200Smm *size = 0; 1756231200Smm *offset = rar->offset; 1757231200Smm if (rar->file_crc != rar->crc_calculated) { 1758231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1759231200Smm "File CRC error"); 1760231200Smm return (ARCHIVE_FATAL); 1761231200Smm } 1762231200Smm rar->entry_eof = 1; 1763231200Smm return (ARCHIVE_EOF); 1764231200Smm } 1765231200Smm 1766248616Smm *buff = rar_read_ahead(a, 1, &bytes_avail); 1767231200Smm if (bytes_avail <= 0) 1768231200Smm { 1769231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1770231200Smm "Truncated RAR file data"); 1771231200Smm return (ARCHIVE_FATAL); 1772231200Smm } 1773231200Smm 1774231200Smm *size = bytes_avail; 1775231200Smm *offset = rar->offset; 1776231200Smm rar->offset += bytes_avail; 1777248616Smm rar->offset_seek += bytes_avail; 1778231200Smm rar->bytes_remaining -= bytes_avail; 1779231200Smm rar->bytes_unconsumed = bytes_avail; 1780231200Smm /* Calculate File CRC. */ 1781248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, 1782248616Smm (unsigned)bytes_avail); 1783231200Smm return (ARCHIVE_OK); 1784231200Smm} 1785231200Smm 1786231200Smmstatic int 1787231200Smmread_data_compressed(struct archive_read *a, const void **buff, size_t *size, 1788231200Smm int64_t *offset) 1789231200Smm{ 1790231200Smm struct rar *rar; 1791231200Smm int64_t start, end, actualend; 1792231200Smm size_t bs; 1793231200Smm int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i; 1794231200Smm 1795231200Smm rar = (struct rar *)(a->format->data); 1796231200Smm 1797231200Smm do { 1798231200Smm if (!rar->valid) 1799231200Smm return (ARCHIVE_FATAL); 1800231200Smm if (rar->ppmd_eod || 1801231200Smm (rar->dictionary_size && rar->offset >= rar->unp_size)) 1802231200Smm { 1803231200Smm if (rar->unp_offset > 0) { 1804231200Smm /* 1805231200Smm * We have unprocessed extracted data. write it out. 1806231200Smm */ 1807231200Smm *buff = rar->unp_buffer; 1808231200Smm *size = rar->unp_offset; 1809231200Smm *offset = rar->offset_outgoing; 1810231200Smm rar->offset_outgoing += *size; 1811231200Smm /* Calculate File CRC. */ 1812248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, 1813248616Smm (unsigned)*size); 1814231200Smm rar->unp_offset = 0; 1815231200Smm return (ARCHIVE_OK); 1816231200Smm } 1817231200Smm *buff = NULL; 1818231200Smm *size = 0; 1819231200Smm *offset = rar->offset; 1820231200Smm if (rar->file_crc != rar->crc_calculated) { 1821231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1822231200Smm "File CRC error"); 1823231200Smm return (ARCHIVE_FATAL); 1824231200Smm } 1825231200Smm rar->entry_eof = 1; 1826231200Smm return (ARCHIVE_EOF); 1827231200Smm } 1828231200Smm 1829231200Smm if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0) 1830231200Smm { 1831231200Smm if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) 1832231200Smm bs = rar->unp_buffer_size - rar->unp_offset; 1833231200Smm else 1834238856Smm bs = (size_t)rar->bytes_uncopied; 1835248616Smm ret = copy_from_lzss_window(a, buff, rar->offset, (int)bs); 1836231200Smm if (ret != ARCHIVE_OK) 1837231200Smm return (ret); 1838231200Smm rar->offset += bs; 1839231200Smm rar->bytes_uncopied -= bs; 1840231200Smm if (*buff != NULL) { 1841231200Smm rar->unp_offset = 0; 1842231200Smm *size = rar->unp_buffer_size; 1843231200Smm *offset = rar->offset_outgoing; 1844231200Smm rar->offset_outgoing += *size; 1845231200Smm /* Calculate File CRC. */ 1846248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, 1847248616Smm (unsigned)*size); 1848231200Smm return (ret); 1849231200Smm } 1850231200Smm continue; 1851231200Smm } 1852231200Smm 1853231200Smm if (!rar->br.next_in && 1854231200Smm (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN) 1855231200Smm return (ret); 1856231200Smm if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN))) 1857231200Smm return (ret); 1858231200Smm 1859231200Smm if (rar->is_ppmd_block) 1860231200Smm { 1861231200Smm if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1862231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1863231200Smm { 1864231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1865231200Smm "Invalid symbol"); 1866231200Smm return (ARCHIVE_FATAL); 1867231200Smm } 1868231200Smm if(sym != rar->ppmd_escape) 1869231200Smm { 1870231200Smm lzss_emit_literal(rar, sym); 1871231200Smm rar->bytes_uncopied++; 1872231200Smm } 1873231200Smm else 1874231200Smm { 1875231200Smm if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1876231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1877231200Smm { 1878231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1879231200Smm "Invalid symbol"); 1880231200Smm return (ARCHIVE_FATAL); 1881231200Smm } 1882231200Smm 1883231200Smm switch(code) 1884231200Smm { 1885231200Smm case 0: 1886231200Smm rar->start_new_table = 1; 1887231200Smm return read_data_compressed(a, buff, size, offset); 1888231200Smm 1889231200Smm case 2: 1890231200Smm rar->ppmd_eod = 1;/* End Of ppmd Data. */ 1891231200Smm continue; 1892231200Smm 1893231200Smm case 3: 1894231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1895231200Smm "Parsing filters is unsupported."); 1896231200Smm return (ARCHIVE_FAILED); 1897231200Smm 1898231200Smm case 4: 1899231200Smm lzss_offset = 0; 1900231200Smm for (i = 2; i >= 0; i--) 1901231200Smm { 1902231200Smm if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1903231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1904231200Smm { 1905231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1906231200Smm "Invalid symbol"); 1907231200Smm return (ARCHIVE_FATAL); 1908231200Smm } 1909231200Smm lzss_offset |= code << (i * 8); 1910231200Smm } 1911231200Smm if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1912231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1913231200Smm { 1914231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1915231200Smm "Invalid symbol"); 1916231200Smm return (ARCHIVE_FATAL); 1917231200Smm } 1918231200Smm lzss_emit_match(rar, lzss_offset + 2, length + 32); 1919231200Smm rar->bytes_uncopied += length + 32; 1920231200Smm break; 1921231200Smm 1922231200Smm case 5: 1923231200Smm if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1924231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1925231200Smm { 1926231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1927231200Smm "Invalid symbol"); 1928231200Smm return (ARCHIVE_FATAL); 1929231200Smm } 1930231200Smm lzss_emit_match(rar, 1, length + 4); 1931231200Smm rar->bytes_uncopied += length + 4; 1932231200Smm break; 1933231200Smm 1934231200Smm default: 1935231200Smm lzss_emit_literal(rar, sym); 1936231200Smm rar->bytes_uncopied++; 1937231200Smm } 1938231200Smm } 1939231200Smm } 1940231200Smm else 1941231200Smm { 1942231200Smm start = rar->offset; 1943231200Smm end = start + rar->dictionary_size; 1944231200Smm rar->filterstart = INT64_MAX; 1945231200Smm 1946231200Smm if ((actualend = expand(a, end)) < 0) 1947231200Smm return ((int)actualend); 1948231200Smm 1949231200Smm rar->bytes_uncopied = actualend - start; 1950231200Smm if (rar->bytes_uncopied == 0) { 1951231200Smm /* Broken RAR files cause this case. 1952231200Smm * NOTE: If this case were possible on a normal RAR file 1953231200Smm * we would find out where it was actually bad and 1954231200Smm * what we would do to solve it. */ 1955231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1956231200Smm "Internal error extracting RAR file"); 1957231200Smm return (ARCHIVE_FATAL); 1958231200Smm } 1959231200Smm } 1960231200Smm if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) 1961231200Smm bs = rar->unp_buffer_size - rar->unp_offset; 1962231200Smm else 1963238856Smm bs = (size_t)rar->bytes_uncopied; 1964248616Smm ret = copy_from_lzss_window(a, buff, rar->offset, (int)bs); 1965231200Smm if (ret != ARCHIVE_OK) 1966231200Smm return (ret); 1967231200Smm rar->offset += bs; 1968231200Smm rar->bytes_uncopied -= bs; 1969231200Smm /* 1970231200Smm * If *buff is NULL, it means unp_buffer is not full. 1971231200Smm * So we have to continue extracting a RAR file. 1972231200Smm */ 1973231200Smm } while (*buff == NULL); 1974231200Smm 1975231200Smm rar->unp_offset = 0; 1976231200Smm *size = rar->unp_buffer_size; 1977231200Smm *offset = rar->offset_outgoing; 1978231200Smm rar->offset_outgoing += *size; 1979231200Smm /* Calculate File CRC. */ 1980248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, (unsigned)*size); 1981231200Smm return ret; 1982231200Smm} 1983231200Smm 1984231200Smmstatic int 1985231200Smmparse_codes(struct archive_read *a) 1986231200Smm{ 1987231200Smm int i, j, val, n, r; 1988231200Smm unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags; 1989231200Smm unsigned int maxorder; 1990231200Smm struct huffman_code precode; 1991231200Smm struct rar *rar = (struct rar *)(a->format->data); 1992231200Smm struct rar_br *br = &(rar->br); 1993231200Smm 1994231200Smm free_codes(a); 1995231200Smm 1996231200Smm /* Skip to the next byte */ 1997231200Smm rar_br_consume_unalined_bits(br); 1998231200Smm 1999231200Smm /* PPMd block flag */ 2000231200Smm if (!rar_br_read_ahead(a, br, 1)) 2001231200Smm goto truncated_data; 2002231200Smm if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0) 2003231200Smm { 2004231200Smm rar_br_consume(br, 1); 2005231200Smm if (!rar_br_read_ahead(a, br, 7)) 2006231200Smm goto truncated_data; 2007231200Smm ppmd_flags = rar_br_bits(br, 7); 2008231200Smm rar_br_consume(br, 7); 2009231200Smm 2010231200Smm /* Memory is allocated in MB */ 2011231200Smm if (ppmd_flags & 0x20) 2012231200Smm { 2013231200Smm if (!rar_br_read_ahead(a, br, 8)) 2014231200Smm goto truncated_data; 2015231200Smm rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20; 2016231200Smm rar_br_consume(br, 8); 2017231200Smm } 2018231200Smm 2019231200Smm if (ppmd_flags & 0x40) 2020231200Smm { 2021231200Smm if (!rar_br_read_ahead(a, br, 8)) 2022231200Smm goto truncated_data; 2023231200Smm rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8); 2024231200Smm rar_br_consume(br, 8); 2025231200Smm } 2026231200Smm else 2027231200Smm rar->ppmd_escape = 2; 2028231200Smm 2029231200Smm if (ppmd_flags & 0x20) 2030231200Smm { 2031231200Smm maxorder = (ppmd_flags & 0x1F) + 1; 2032231200Smm if(maxorder > 16) 2033231200Smm maxorder = 16 + (maxorder - 16) * 3; 2034231200Smm 2035231200Smm if (maxorder == 1) 2036231200Smm { 2037231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2038231200Smm "Truncated RAR file data"); 2039231200Smm return (ARCHIVE_FATAL); 2040231200Smm } 2041231200Smm 2042231200Smm /* Make sure ppmd7_contest is freed before Ppmd7_Construct 2043231200Smm * because reading a broken file cause this abnormal sequence. */ 2044231200Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc); 2045231200Smm 2046231200Smm rar->bytein.a = a; 2047231200Smm rar->bytein.Read = &ppmd_read; 2048231200Smm __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec); 2049231200Smm rar->range_dec.Stream = &rar->bytein; 2050231200Smm __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context); 2051231200Smm 2052231200Smm if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context, 2053231200Smm rar->dictionary_size, &g_szalloc)) 2054231200Smm { 2055231200Smm archive_set_error(&a->archive, ENOMEM, 2056231200Smm "Out of memory"); 2057231200Smm return (ARCHIVE_FATAL); 2058231200Smm } 2059231200Smm if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) 2060231200Smm { 2061231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2062231200Smm "Unable to initialize PPMd range decoder"); 2063231200Smm return (ARCHIVE_FATAL); 2064231200Smm } 2065231200Smm __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder); 2066231200Smm rar->ppmd_valid = 1; 2067231200Smm } 2068231200Smm else 2069231200Smm { 2070231200Smm if (!rar->ppmd_valid) { 2071231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2072231200Smm "Invalid PPMd sequence"); 2073231200Smm return (ARCHIVE_FATAL); 2074231200Smm } 2075231200Smm if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) 2076231200Smm { 2077231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2078231200Smm "Unable to initialize PPMd range decoder"); 2079231200Smm return (ARCHIVE_FATAL); 2080231200Smm } 2081231200Smm } 2082231200Smm } 2083231200Smm else 2084231200Smm { 2085231200Smm rar_br_consume(br, 1); 2086231200Smm 2087231200Smm /* Keep existing table flag */ 2088231200Smm if (!rar_br_read_ahead(a, br, 1)) 2089231200Smm goto truncated_data; 2090231200Smm if (!rar_br_bits(br, 1)) 2091231200Smm memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); 2092231200Smm rar_br_consume(br, 1); 2093231200Smm 2094231200Smm memset(&bitlengths, 0, sizeof(bitlengths)); 2095231200Smm for (i = 0; i < MAX_SYMBOLS;) 2096231200Smm { 2097231200Smm if (!rar_br_read_ahead(a, br, 4)) 2098231200Smm goto truncated_data; 2099231200Smm bitlengths[i++] = rar_br_bits(br, 4); 2100231200Smm rar_br_consume(br, 4); 2101231200Smm if (bitlengths[i-1] == 0xF) 2102231200Smm { 2103231200Smm if (!rar_br_read_ahead(a, br, 4)) 2104231200Smm goto truncated_data; 2105231200Smm zerocount = rar_br_bits(br, 4); 2106231200Smm rar_br_consume(br, 4); 2107231200Smm if (zerocount) 2108231200Smm { 2109231200Smm i--; 2110231200Smm for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++) 2111231200Smm bitlengths[i++] = 0; 2112231200Smm } 2113231200Smm } 2114231200Smm } 2115231200Smm 2116231200Smm memset(&precode, 0, sizeof(precode)); 2117231200Smm r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH); 2118231200Smm if (r != ARCHIVE_OK) { 2119231200Smm free(precode.tree); 2120231200Smm free(precode.table); 2121231200Smm return (r); 2122231200Smm } 2123231200Smm 2124231200Smm for (i = 0; i < HUFFMAN_TABLE_SIZE;) 2125231200Smm { 2126231200Smm if ((val = read_next_symbol(a, &precode)) < 0) { 2127231200Smm free(precode.tree); 2128231200Smm free(precode.table); 2129231200Smm return (ARCHIVE_FATAL); 2130231200Smm } 2131231200Smm if (val < 16) 2132231200Smm { 2133231200Smm rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF; 2134231200Smm i++; 2135231200Smm } 2136231200Smm else if (val < 18) 2137231200Smm { 2138231200Smm if (i == 0) 2139231200Smm { 2140231200Smm free(precode.tree); 2141231200Smm free(precode.table); 2142231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2143231200Smm "Internal error extracting RAR file."); 2144231200Smm return (ARCHIVE_FATAL); 2145231200Smm } 2146231200Smm 2147231200Smm if(val == 16) { 2148231200Smm if (!rar_br_read_ahead(a, br, 3)) { 2149231200Smm free(precode.tree); 2150231200Smm free(precode.table); 2151231200Smm goto truncated_data; 2152231200Smm } 2153231200Smm n = rar_br_bits(br, 3) + 3; 2154231200Smm rar_br_consume(br, 3); 2155231200Smm } else { 2156231200Smm if (!rar_br_read_ahead(a, br, 7)) { 2157231200Smm free(precode.tree); 2158231200Smm free(precode.table); 2159231200Smm goto truncated_data; 2160231200Smm } 2161231200Smm n = rar_br_bits(br, 7) + 11; 2162231200Smm rar_br_consume(br, 7); 2163231200Smm } 2164231200Smm 2165231200Smm for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) 2166231200Smm { 2167231200Smm rar->lengthtable[i] = rar->lengthtable[i-1]; 2168231200Smm i++; 2169231200Smm } 2170231200Smm } 2171231200Smm else 2172231200Smm { 2173231200Smm if(val == 18) { 2174231200Smm if (!rar_br_read_ahead(a, br, 3)) { 2175231200Smm free(precode.tree); 2176231200Smm free(precode.table); 2177231200Smm goto truncated_data; 2178231200Smm } 2179231200Smm n = rar_br_bits(br, 3) + 3; 2180231200Smm rar_br_consume(br, 3); 2181231200Smm } else { 2182231200Smm if (!rar_br_read_ahead(a, br, 7)) { 2183231200Smm free(precode.tree); 2184231200Smm free(precode.table); 2185231200Smm goto truncated_data; 2186231200Smm } 2187231200Smm n = rar_br_bits(br, 7) + 11; 2188231200Smm rar_br_consume(br, 7); 2189231200Smm } 2190231200Smm 2191231200Smm for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) 2192231200Smm rar->lengthtable[i++] = 0; 2193231200Smm } 2194231200Smm } 2195231200Smm free(precode.tree); 2196231200Smm free(precode.table); 2197231200Smm 2198231200Smm r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE, 2199231200Smm MAX_SYMBOL_LENGTH); 2200231200Smm if (r != ARCHIVE_OK) 2201231200Smm return (r); 2202231200Smm r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE], 2203231200Smm OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); 2204231200Smm if (r != ARCHIVE_OK) 2205231200Smm return (r); 2206231200Smm r = create_code(a, &rar->lowoffsetcode, 2207231200Smm &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE], 2208231200Smm LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); 2209231200Smm if (r != ARCHIVE_OK) 2210231200Smm return (r); 2211231200Smm r = create_code(a, &rar->lengthcode, 2212231200Smm &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE + 2213231200Smm LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH); 2214231200Smm if (r != ARCHIVE_OK) 2215231200Smm return (r); 2216231200Smm } 2217231200Smm 2218231200Smm if (!rar->dictionary_size || !rar->lzss.window) 2219231200Smm { 2220231200Smm /* Seems as though dictionary sizes are not used. Even so, minimize 2221231200Smm * memory usage as much as possible. 2222231200Smm */ 2223248616Smm void *new_window; 2224248616Smm unsigned int new_size; 2225248616Smm 2226231200Smm if (rar->unp_size >= DICTIONARY_MAX_SIZE) 2227248616Smm new_size = DICTIONARY_MAX_SIZE; 2228231200Smm else 2229248616Smm new_size = rar_fls((unsigned int)rar->unp_size) << 1; 2230248616Smm new_window = realloc(rar->lzss.window, new_size); 2231248616Smm if (new_window == NULL) { 2232231200Smm archive_set_error(&a->archive, ENOMEM, 2233231200Smm "Unable to allocate memory for uncompressed data."); 2234231200Smm return (ARCHIVE_FATAL); 2235231200Smm } 2236248616Smm rar->lzss.window = (unsigned char *)new_window; 2237248616Smm rar->dictionary_size = new_size; 2238231200Smm memset(rar->lzss.window, 0, rar->dictionary_size); 2239231200Smm rar->lzss.mask = rar->dictionary_size - 1; 2240231200Smm } 2241231200Smm 2242231200Smm rar->start_new_table = 0; 2243231200Smm return (ARCHIVE_OK); 2244231200Smmtruncated_data: 2245231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2246231200Smm "Truncated RAR file data"); 2247231200Smm rar->valid = 0; 2248231200Smm return (ARCHIVE_FATAL); 2249231200Smm} 2250231200Smm 2251231200Smmstatic void 2252231200Smmfree_codes(struct archive_read *a) 2253231200Smm{ 2254231200Smm struct rar *rar = (struct rar *)(a->format->data); 2255231200Smm free(rar->maincode.tree); 2256231200Smm free(rar->offsetcode.tree); 2257231200Smm free(rar->lowoffsetcode.tree); 2258231200Smm free(rar->lengthcode.tree); 2259231200Smm free(rar->maincode.table); 2260231200Smm free(rar->offsetcode.table); 2261231200Smm free(rar->lowoffsetcode.table); 2262231200Smm free(rar->lengthcode.table); 2263231200Smm memset(&rar->maincode, 0, sizeof(rar->maincode)); 2264231200Smm memset(&rar->offsetcode, 0, sizeof(rar->offsetcode)); 2265231200Smm memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode)); 2266231200Smm memset(&rar->lengthcode, 0, sizeof(rar->lengthcode)); 2267231200Smm} 2268231200Smm 2269231200Smm 2270231200Smmstatic int 2271231200Smmread_next_symbol(struct archive_read *a, struct huffman_code *code) 2272231200Smm{ 2273231200Smm unsigned char bit; 2274231200Smm unsigned int bits; 2275231200Smm int length, value, node; 2276231200Smm struct rar *rar; 2277231200Smm struct rar_br *br; 2278231200Smm 2279231200Smm if (!code->table) 2280231200Smm { 2281231200Smm if (make_table(a, code) != (ARCHIVE_OK)) 2282231200Smm return -1; 2283231200Smm } 2284231200Smm 2285231200Smm rar = (struct rar *)(a->format->data); 2286231200Smm br = &(rar->br); 2287231200Smm 2288231200Smm /* Look ahead (peek) at bits */ 2289231200Smm if (!rar_br_read_ahead(a, br, code->tablesize)) { 2290231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2291231200Smm "Truncated RAR file data"); 2292231200Smm rar->valid = 0; 2293231200Smm return -1; 2294231200Smm } 2295231200Smm bits = rar_br_bits(br, code->tablesize); 2296231200Smm 2297231200Smm length = code->table[bits].length; 2298231200Smm value = code->table[bits].value; 2299231200Smm 2300231200Smm if (length < 0) 2301231200Smm { 2302231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2303231200Smm "Invalid prefix code in bitstream"); 2304231200Smm return -1; 2305231200Smm } 2306231200Smm 2307231200Smm if (length <= code->tablesize) 2308231200Smm { 2309231200Smm /* Skip length bits */ 2310231200Smm rar_br_consume(br, length); 2311231200Smm return value; 2312231200Smm } 2313231200Smm 2314231200Smm /* Skip tablesize bits */ 2315231200Smm rar_br_consume(br, code->tablesize); 2316231200Smm 2317231200Smm node = value; 2318231200Smm while (!(code->tree[node].branches[0] == 2319231200Smm code->tree[node].branches[1])) 2320231200Smm { 2321231200Smm if (!rar_br_read_ahead(a, br, 1)) { 2322231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2323231200Smm "Truncated RAR file data"); 2324231200Smm rar->valid = 0; 2325231200Smm return -1; 2326231200Smm } 2327231200Smm bit = rar_br_bits(br, 1); 2328231200Smm rar_br_consume(br, 1); 2329231200Smm 2330231200Smm if (code->tree[node].branches[bit] < 0) 2331231200Smm { 2332231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2333231200Smm "Invalid prefix code in bitstream"); 2334231200Smm return -1; 2335231200Smm } 2336231200Smm node = code->tree[node].branches[bit]; 2337231200Smm } 2338231200Smm 2339231200Smm return code->tree[node].branches[0]; 2340231200Smm} 2341231200Smm 2342231200Smmstatic int 2343231200Smmcreate_code(struct archive_read *a, struct huffman_code *code, 2344231200Smm unsigned char *lengths, int numsymbols, char maxlength) 2345231200Smm{ 2346231200Smm int i, j, codebits = 0, symbolsleft = numsymbols; 2347231200Smm 2348231200Smm if (new_node(code) < 0) { 2349231200Smm archive_set_error(&a->archive, ENOMEM, 2350231200Smm "Unable to allocate memory for node data."); 2351231200Smm return (ARCHIVE_FATAL); 2352231200Smm } 2353231200Smm code->numentries = 1; 2354231200Smm code->minlength = INT_MAX; 2355231200Smm code->maxlength = INT_MIN; 2356231200Smm codebits = 0; 2357231200Smm for(i = 1; i <= maxlength; i++) 2358231200Smm { 2359231200Smm for(j = 0; j < numsymbols; j++) 2360231200Smm { 2361231200Smm if (lengths[j] != i) continue; 2362231200Smm if (add_value(a, code, j, codebits, i) != ARCHIVE_OK) 2363231200Smm return (ARCHIVE_FATAL); 2364231200Smm codebits++; 2365231200Smm if (--symbolsleft <= 0) { break; break; } 2366231200Smm } 2367231200Smm codebits <<= 1; 2368231200Smm } 2369231200Smm return (ARCHIVE_OK); 2370231200Smm} 2371231200Smm 2372231200Smmstatic int 2373231200Smmadd_value(struct archive_read *a, struct huffman_code *code, int value, 2374231200Smm int codebits, int length) 2375231200Smm{ 2376231200Smm int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode; 2377231200Smm 2378231200Smm free(code->table); 2379231200Smm code->table = NULL; 2380231200Smm 2381231200Smm if(length > code->maxlength) 2382231200Smm code->maxlength = length; 2383231200Smm if(length < code->minlength) 2384231200Smm code->minlength = length; 2385231200Smm 2386231200Smm repeatpos = -1; 2387231200Smm if (repeatpos == 0 || (repeatpos >= 0 2388231200Smm && (((codebits >> (repeatpos - 1)) & 3) == 0 2389231200Smm || ((codebits >> (repeatpos - 1)) & 3) == 3))) 2390231200Smm { 2391231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2392231200Smm "Invalid repeat position"); 2393231200Smm return (ARCHIVE_FATAL); 2394231200Smm } 2395231200Smm 2396231200Smm lastnode = 0; 2397231200Smm for (bitpos = length - 1; bitpos >= 0; bitpos--) 2398231200Smm { 2399231200Smm bit = (codebits >> bitpos) & 1; 2400231200Smm 2401231200Smm /* Leaf node check */ 2402231200Smm if (code->tree[lastnode].branches[0] == 2403231200Smm code->tree[lastnode].branches[1]) 2404231200Smm { 2405231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2406231200Smm "Prefix found"); 2407231200Smm return (ARCHIVE_FATAL); 2408231200Smm } 2409231200Smm 2410231200Smm if (bitpos == repeatpos) 2411231200Smm { 2412231200Smm /* Open branch check */ 2413231200Smm if (!(code->tree[lastnode].branches[bit] < 0)) 2414231200Smm { 2415231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2416231200Smm "Invalid repeating code"); 2417231200Smm return (ARCHIVE_FATAL); 2418231200Smm } 2419231200Smm 2420231200Smm if ((repeatnode = new_node(code)) < 0) { 2421231200Smm archive_set_error(&a->archive, ENOMEM, 2422231200Smm "Unable to allocate memory for node data."); 2423231200Smm return (ARCHIVE_FATAL); 2424231200Smm } 2425231200Smm if ((nextnode = new_node(code)) < 0) { 2426231200Smm archive_set_error(&a->archive, ENOMEM, 2427231200Smm "Unable to allocate memory for node data."); 2428231200Smm return (ARCHIVE_FATAL); 2429231200Smm } 2430231200Smm 2431231200Smm /* Set branches */ 2432231200Smm code->tree[lastnode].branches[bit] = repeatnode; 2433231200Smm code->tree[repeatnode].branches[bit] = repeatnode; 2434231200Smm code->tree[repeatnode].branches[bit^1] = nextnode; 2435231200Smm lastnode = nextnode; 2436231200Smm 2437231200Smm bitpos++; /* terminating bit already handled, skip it */ 2438231200Smm } 2439231200Smm else 2440231200Smm { 2441231200Smm /* Open branch check */ 2442231200Smm if (code->tree[lastnode].branches[bit] < 0) 2443231200Smm { 2444231200Smm if (new_node(code) < 0) { 2445231200Smm archive_set_error(&a->archive, ENOMEM, 2446231200Smm "Unable to allocate memory for node data."); 2447231200Smm return (ARCHIVE_FATAL); 2448231200Smm } 2449231200Smm code->tree[lastnode].branches[bit] = code->numentries++; 2450231200Smm } 2451231200Smm 2452231200Smm /* set to branch */ 2453231200Smm lastnode = code->tree[lastnode].branches[bit]; 2454231200Smm } 2455231200Smm } 2456231200Smm 2457231200Smm if (!(code->tree[lastnode].branches[0] == -1 2458231200Smm && code->tree[lastnode].branches[1] == -2)) 2459231200Smm { 2460231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2461231200Smm "Prefix found"); 2462231200Smm return (ARCHIVE_FATAL); 2463231200Smm } 2464231200Smm 2465231200Smm /* Set leaf value */ 2466231200Smm code->tree[lastnode].branches[0] = value; 2467231200Smm code->tree[lastnode].branches[1] = value; 2468231200Smm 2469231200Smm return (ARCHIVE_OK); 2470231200Smm} 2471231200Smm 2472231200Smmstatic int 2473231200Smmnew_node(struct huffman_code *code) 2474231200Smm{ 2475248616Smm void *new_tree; 2476248616Smm 2477248616Smm new_tree = realloc(code->tree, (code->numentries + 1) * sizeof(*code->tree)); 2478248616Smm if (new_tree == NULL) 2479231200Smm return (-1); 2480248616Smm code->tree = (struct huffman_tree_node *)new_tree; 2481231200Smm code->tree[code->numentries].branches[0] = -1; 2482231200Smm code->tree[code->numentries].branches[1] = -2; 2483231200Smm return 1; 2484231200Smm} 2485231200Smm 2486231200Smmstatic int 2487231200Smmmake_table(struct archive_read *a, struct huffman_code *code) 2488231200Smm{ 2489231200Smm if (code->maxlength < code->minlength || code->maxlength > 10) 2490231200Smm code->tablesize = 10; 2491231200Smm else 2492231200Smm code->tablesize = code->maxlength; 2493231200Smm 2494231200Smm code->table = 2495248616Smm (struct huffman_table_entry *)calloc(1, sizeof(*code->table) 2496248616Smm * ((size_t)1 << code->tablesize)); 2497231200Smm 2498231200Smm return make_table_recurse(a, code, 0, code->table, 0, code->tablesize); 2499231200Smm} 2500231200Smm 2501231200Smmstatic int 2502231200Smmmake_table_recurse(struct archive_read *a, struct huffman_code *code, int node, 2503231200Smm struct huffman_table_entry *table, int depth, 2504231200Smm int maxdepth) 2505231200Smm{ 2506231200Smm int currtablesize, i, ret = (ARCHIVE_OK); 2507231200Smm 2508231200Smm if (!code->tree) 2509231200Smm { 2510231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2511231200Smm "Huffman tree was not created."); 2512231200Smm return (ARCHIVE_FATAL); 2513231200Smm } 2514231200Smm if (node < 0 || node >= code->numentries) 2515231200Smm { 2516231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2517231200Smm "Invalid location to Huffman tree specified."); 2518231200Smm return (ARCHIVE_FATAL); 2519231200Smm } 2520231200Smm 2521231200Smm currtablesize = 1 << (maxdepth - depth); 2522231200Smm 2523231200Smm if (code->tree[node].branches[0] == 2524231200Smm code->tree[node].branches[1]) 2525231200Smm { 2526231200Smm for(i = 0; i < currtablesize; i++) 2527231200Smm { 2528231200Smm table[i].length = depth; 2529231200Smm table[i].value = code->tree[node].branches[0]; 2530231200Smm } 2531231200Smm } 2532231200Smm else if (node < 0) 2533231200Smm { 2534231200Smm for(i = 0; i < currtablesize; i++) 2535231200Smm table[i].length = -1; 2536231200Smm } 2537231200Smm else 2538231200Smm { 2539231200Smm if(depth == maxdepth) 2540231200Smm { 2541231200Smm table[0].length = maxdepth + 1; 2542231200Smm table[0].value = node; 2543231200Smm } 2544231200Smm else 2545231200Smm { 2546231200Smm ret |= make_table_recurse(a, code, code->tree[node].branches[0], table, 2547231200Smm depth + 1, maxdepth); 2548231200Smm ret |= make_table_recurse(a, code, code->tree[node].branches[1], 2549231200Smm table + currtablesize / 2, depth + 1, maxdepth); 2550231200Smm } 2551231200Smm } 2552231200Smm return ret; 2553231200Smm} 2554231200Smm 2555231200Smmstatic int64_t 2556231200Smmexpand(struct archive_read *a, int64_t end) 2557231200Smm{ 2558231200Smm static const unsigned char lengthbases[] = 2559231200Smm { 0, 1, 2, 3, 4, 5, 6, 2560231200Smm 7, 8, 10, 12, 14, 16, 20, 2561231200Smm 24, 28, 32, 40, 48, 56, 64, 2562231200Smm 80, 96, 112, 128, 160, 192, 224 }; 2563231200Smm static const unsigned char lengthbits[] = 2564231200Smm { 0, 0, 0, 0, 0, 0, 0, 2565231200Smm 0, 1, 1, 1, 1, 2, 2, 2566231200Smm 2, 2, 3, 3, 3, 3, 4, 2567231200Smm 4, 4, 4, 5, 5, 5, 5 }; 2568231200Smm static const unsigned int offsetbases[] = 2569231200Smm { 0, 1, 2, 3, 4, 6, 2570231200Smm 8, 12, 16, 24, 32, 48, 2571231200Smm 64, 96, 128, 192, 256, 384, 2572231200Smm 512, 768, 1024, 1536, 2048, 3072, 2573231200Smm 4096, 6144, 8192, 12288, 16384, 24576, 2574231200Smm 32768, 49152, 65536, 98304, 131072, 196608, 2575231200Smm 262144, 327680, 393216, 458752, 524288, 589824, 2576231200Smm 655360, 720896, 786432, 851968, 917504, 983040, 2577231200Smm 1048576, 1310720, 1572864, 1835008, 2097152, 2359296, 2578231200Smm 2621440, 2883584, 3145728, 3407872, 3670016, 3932160 }; 2579231200Smm static const unsigned char offsetbits[] = 2580231200Smm { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 2581231200Smm 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 2582231200Smm 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 2583231200Smm 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2584231200Smm 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; 2585231200Smm static const unsigned char shortbases[] = 2586231200Smm { 0, 4, 8, 16, 32, 64, 128, 192 }; 2587231200Smm static const unsigned char shortbits[] = 2588231200Smm { 2, 2, 3, 4, 5, 6, 6, 6 }; 2589231200Smm 2590231200Smm int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol; 2591231200Smm unsigned char newfile; 2592231200Smm struct rar *rar = (struct rar *)(a->format->data); 2593231200Smm struct rar_br *br = &(rar->br); 2594231200Smm 2595231200Smm if (rar->filterstart < end) 2596231200Smm end = rar->filterstart; 2597231200Smm 2598231200Smm while (1) 2599231200Smm { 2600231200Smm if (rar->output_last_match && 2601231200Smm lzss_position(&rar->lzss) + rar->lastlength <= end) 2602231200Smm { 2603231200Smm lzss_emit_match(rar, rar->lastoffset, rar->lastlength); 2604231200Smm rar->output_last_match = 0; 2605231200Smm } 2606231200Smm 2607231200Smm if(rar->is_ppmd_block || rar->output_last_match || 2608231200Smm lzss_position(&rar->lzss) >= end) 2609231200Smm return lzss_position(&rar->lzss); 2610231200Smm 2611231200Smm if ((symbol = read_next_symbol(a, &rar->maincode)) < 0) 2612231200Smm return (ARCHIVE_FATAL); 2613231200Smm rar->output_last_match = 0; 2614231200Smm 2615231200Smm if (symbol < 256) 2616231200Smm { 2617231200Smm lzss_emit_literal(rar, symbol); 2618231200Smm continue; 2619231200Smm } 2620231200Smm else if (symbol == 256) 2621231200Smm { 2622231200Smm if (!rar_br_read_ahead(a, br, 1)) 2623231200Smm goto truncated_data; 2624231200Smm newfile = !rar_br_bits(br, 1); 2625231200Smm rar_br_consume(br, 1); 2626231200Smm 2627231200Smm if(newfile) 2628231200Smm { 2629231200Smm rar->start_new_block = 1; 2630231200Smm if (!rar_br_read_ahead(a, br, 1)) 2631231200Smm goto truncated_data; 2632231200Smm rar->start_new_table = rar_br_bits(br, 1); 2633231200Smm rar_br_consume(br, 1); 2634231200Smm return lzss_position(&rar->lzss); 2635231200Smm } 2636231200Smm else 2637231200Smm { 2638231200Smm if (parse_codes(a) != ARCHIVE_OK) 2639231200Smm return (ARCHIVE_FATAL); 2640231200Smm continue; 2641231200Smm } 2642231200Smm } 2643231200Smm else if(symbol==257) 2644231200Smm { 2645231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 2646231200Smm "Parsing filters is unsupported."); 2647231200Smm return (ARCHIVE_FAILED); 2648231200Smm } 2649231200Smm else if(symbol==258) 2650231200Smm { 2651231200Smm if(rar->lastlength == 0) 2652231200Smm continue; 2653231200Smm 2654231200Smm offs = rar->lastoffset; 2655231200Smm len = rar->lastlength; 2656231200Smm } 2657231200Smm else if (symbol <= 262) 2658231200Smm { 2659231200Smm offsindex = symbol - 259; 2660231200Smm offs = rar->oldoffset[offsindex]; 2661231200Smm 2662231200Smm if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0) 2663231200Smm goto bad_data; 2664232153Smm if (lensymbol > (int)(sizeof(lengthbases)/sizeof(lengthbases[0]))) 2665231200Smm goto bad_data; 2666232153Smm if (lensymbol > (int)(sizeof(lengthbits)/sizeof(lengthbits[0]))) 2667231200Smm goto bad_data; 2668231200Smm len = lengthbases[lensymbol] + 2; 2669231200Smm if (lengthbits[lensymbol] > 0) { 2670231200Smm if (!rar_br_read_ahead(a, br, lengthbits[lensymbol])) 2671231200Smm goto truncated_data; 2672231200Smm len += rar_br_bits(br, lengthbits[lensymbol]); 2673231200Smm rar_br_consume(br, lengthbits[lensymbol]); 2674231200Smm } 2675231200Smm 2676231200Smm for (i = offsindex; i > 0; i--) 2677231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2678231200Smm rar->oldoffset[0] = offs; 2679231200Smm } 2680231200Smm else if(symbol<=270) 2681231200Smm { 2682231200Smm offs = shortbases[symbol-263] + 1; 2683231200Smm if(shortbits[symbol-263] > 0) { 2684231200Smm if (!rar_br_read_ahead(a, br, shortbits[symbol-263])) 2685231200Smm goto truncated_data; 2686231200Smm offs += rar_br_bits(br, shortbits[symbol-263]); 2687231200Smm rar_br_consume(br, shortbits[symbol-263]); 2688231200Smm } 2689231200Smm 2690231200Smm len = 2; 2691231200Smm 2692231200Smm for(i = 3; i > 0; i--) 2693231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2694231200Smm rar->oldoffset[0] = offs; 2695231200Smm } 2696231200Smm else 2697231200Smm { 2698232153Smm if (symbol-271 > (int)(sizeof(lengthbases)/sizeof(lengthbases[0]))) 2699231200Smm goto bad_data; 2700232153Smm if (symbol-271 > (int)(sizeof(lengthbits)/sizeof(lengthbits[0]))) 2701231200Smm goto bad_data; 2702231200Smm len = lengthbases[symbol-271]+3; 2703231200Smm if(lengthbits[symbol-271] > 0) { 2704231200Smm if (!rar_br_read_ahead(a, br, lengthbits[symbol-271])) 2705231200Smm goto truncated_data; 2706231200Smm len += rar_br_bits(br, lengthbits[symbol-271]); 2707231200Smm rar_br_consume(br, lengthbits[symbol-271]); 2708231200Smm } 2709231200Smm 2710231200Smm if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0) 2711231200Smm goto bad_data; 2712232153Smm if (offssymbol > (int)(sizeof(offsetbases)/sizeof(offsetbases[0]))) 2713231200Smm goto bad_data; 2714232153Smm if (offssymbol > (int)(sizeof(offsetbits)/sizeof(offsetbits[0]))) 2715231200Smm goto bad_data; 2716231200Smm offs = offsetbases[offssymbol]+1; 2717231200Smm if(offsetbits[offssymbol] > 0) 2718231200Smm { 2719231200Smm if(offssymbol > 9) 2720231200Smm { 2721231200Smm if(offsetbits[offssymbol] > 4) { 2722231200Smm if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4)) 2723231200Smm goto truncated_data; 2724231200Smm offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4; 2725231200Smm rar_br_consume(br, offsetbits[offssymbol] - 4); 2726231200Smm } 2727231200Smm 2728231200Smm if(rar->numlowoffsetrepeats > 0) 2729231200Smm { 2730231200Smm rar->numlowoffsetrepeats--; 2731231200Smm offs += rar->lastlowoffset; 2732231200Smm } 2733231200Smm else 2734231200Smm { 2735231200Smm if ((lowoffsetsymbol = 2736231200Smm read_next_symbol(a, &rar->lowoffsetcode)) < 0) 2737231200Smm return (ARCHIVE_FATAL); 2738231200Smm if(lowoffsetsymbol == 16) 2739231200Smm { 2740231200Smm rar->numlowoffsetrepeats = 15; 2741231200Smm offs += rar->lastlowoffset; 2742231200Smm } 2743231200Smm else 2744231200Smm { 2745231200Smm offs += lowoffsetsymbol; 2746231200Smm rar->lastlowoffset = lowoffsetsymbol; 2747231200Smm } 2748231200Smm } 2749231200Smm } 2750231200Smm else { 2751231200Smm if (!rar_br_read_ahead(a, br, offsetbits[offssymbol])) 2752231200Smm goto truncated_data; 2753231200Smm offs += rar_br_bits(br, offsetbits[offssymbol]); 2754231200Smm rar_br_consume(br, offsetbits[offssymbol]); 2755231200Smm } 2756231200Smm } 2757231200Smm 2758231200Smm if (offs >= 0x40000) 2759231200Smm len++; 2760231200Smm if (offs >= 0x2000) 2761231200Smm len++; 2762231200Smm 2763231200Smm for(i = 3; i > 0; i--) 2764231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2765231200Smm rar->oldoffset[0] = offs; 2766231200Smm } 2767231200Smm 2768231200Smm rar->lastoffset = offs; 2769231200Smm rar->lastlength = len; 2770231200Smm rar->output_last_match = 1; 2771231200Smm } 2772231200Smmtruncated_data: 2773231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2774231200Smm "Truncated RAR file data"); 2775231200Smm rar->valid = 0; 2776231200Smm return (ARCHIVE_FATAL); 2777231200Smmbad_data: 2778231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2779231200Smm "Bad RAR file data"); 2780231200Smm return (ARCHIVE_FATAL); 2781231200Smm} 2782231200Smm 2783231200Smmstatic int 2784231200Smmcopy_from_lzss_window(struct archive_read *a, const void **buffer, 2785231200Smm int64_t startpos, int length) 2786231200Smm{ 2787231200Smm int windowoffs, firstpart; 2788231200Smm struct rar *rar = (struct rar *)(a->format->data); 2789231200Smm 2790231200Smm if (!rar->unp_buffer) 2791231200Smm { 2792231200Smm if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL) 2793231200Smm { 2794231200Smm archive_set_error(&a->archive, ENOMEM, 2795231200Smm "Unable to allocate memory for uncompressed data."); 2796231200Smm return (ARCHIVE_FATAL); 2797231200Smm } 2798231200Smm } 2799231200Smm 2800231200Smm windowoffs = lzss_offset_for_position(&rar->lzss, startpos); 2801231200Smm if(windowoffs + length <= lzss_size(&rar->lzss)) 2802231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs], 2803231200Smm length); 2804231200Smm else 2805231200Smm { 2806231200Smm firstpart = lzss_size(&rar->lzss) - windowoffs; 2807231200Smm if (firstpart < 0) { 2808231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2809231200Smm "Bad RAR file data"); 2810231200Smm return (ARCHIVE_FATAL); 2811231200Smm } 2812231200Smm if (firstpart < length) { 2813231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], 2814231200Smm &rar->lzss.window[windowoffs], firstpart); 2815231200Smm memcpy(&rar->unp_buffer[rar->unp_offset + firstpart], 2816231200Smm &rar->lzss.window[0], length - firstpart); 2817231200Smm } else 2818231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], 2819231200Smm &rar->lzss.window[windowoffs], length); 2820231200Smm } 2821231200Smm rar->unp_offset += length; 2822231200Smm if (rar->unp_offset >= rar->unp_buffer_size) 2823231200Smm *buffer = rar->unp_buffer; 2824231200Smm else 2825231200Smm *buffer = NULL; 2826231200Smm return (ARCHIVE_OK); 2827231200Smm} 2828248616Smm 2829248616Smmstatic const void * 2830248616Smmrar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail) 2831248616Smm{ 2832248616Smm struct rar *rar = (struct rar *)(a->format->data); 2833248616Smm const void *h = __archive_read_ahead(a, min, avail); 2834248616Smm int ret; 2835248616Smm if (avail) 2836248616Smm { 2837248616Smm if (a->read_data_is_posix_read && *avail > (ssize_t)a->read_data_requested) 2838248616Smm *avail = a->read_data_requested; 2839248616Smm if (*avail > rar->bytes_remaining) 2840248616Smm *avail = (ssize_t)rar->bytes_remaining; 2841248616Smm if (*avail < 0) 2842248616Smm return NULL; 2843248616Smm else if (*avail == 0 && rar->main_flags & MHD_VOLUME && 2844248616Smm rar->file_flags & FHD_SPLIT_AFTER) 2845248616Smm { 2846248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 2847248616Smm if (ret == (ARCHIVE_EOF)) 2848248616Smm { 2849248616Smm rar->has_endarc_header = 1; 2850248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 2851248616Smm } 2852248616Smm if (ret != (ARCHIVE_OK)) 2853248616Smm return NULL; 2854248616Smm return rar_read_ahead(a, min, avail); 2855248616Smm } 2856248616Smm } 2857248616Smm return h; 2858248616Smm} 2859