archive_read_support_format_rar.c revision 348607
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; 189299529Smm int numallocatedentries; 190231200Smm int minlength; 191231200Smm int maxlength; 192231200Smm int tablesize; 193231200Smm struct huffman_table_entry *table; 194231200Smm}; 195231200Smm 196231200Smmstruct lzss 197231200Smm{ 198231200Smm unsigned char *window; 199231200Smm int mask; 200231200Smm int64_t position; 201231200Smm}; 202231200Smm 203248616Smmstruct data_block_offsets 204248616Smm{ 205248616Smm int64_t header_size; 206248616Smm int64_t start_offset; 207248616Smm int64_t end_offset; 208248616Smm}; 209248616Smm 210231200Smmstruct rar 211231200Smm{ 212231200Smm /* Entries from main RAR header */ 213231200Smm unsigned main_flags; 214231200Smm unsigned long file_crc; 215231200Smm char reserved1[2]; 216231200Smm char reserved2[4]; 217231200Smm char encryptver; 218231200Smm 219231200Smm /* File header entries */ 220231200Smm char compression_method; 221231200Smm unsigned file_flags; 222231200Smm int64_t packed_size; 223231200Smm int64_t unp_size; 224231200Smm time_t mtime; 225231200Smm long mnsec; 226231200Smm mode_t mode; 227231200Smm char *filename; 228248616Smm char *filename_save; 229299529Smm size_t filename_save_size; 230231200Smm size_t filename_allocated; 231231200Smm 232231200Smm /* File header optional entries */ 233231200Smm char salt[8]; 234231200Smm time_t atime; 235231200Smm long ansec; 236231200Smm time_t ctime; 237231200Smm long cnsec; 238231200Smm time_t arctime; 239231200Smm long arcnsec; 240231200Smm 241231200Smm /* Fields to help with tracking decompression of files. */ 242231200Smm int64_t bytes_unconsumed; 243231200Smm int64_t bytes_remaining; 244231200Smm int64_t bytes_uncopied; 245231200Smm int64_t offset; 246231200Smm int64_t offset_outgoing; 247248616Smm int64_t offset_seek; 248231200Smm char valid; 249231200Smm unsigned int unp_offset; 250231200Smm unsigned int unp_buffer_size; 251231200Smm unsigned char *unp_buffer; 252231200Smm unsigned int dictionary_size; 253231200Smm char start_new_block; 254231200Smm char entry_eof; 255231200Smm unsigned long crc_calculated; 256231200Smm int found_first_header; 257248616Smm char has_endarc_header; 258248616Smm struct data_block_offsets *dbo; 259248616Smm unsigned int cursor; 260248616Smm unsigned int nodes; 261342360Smm char filename_must_match; 262231200Smm 263231200Smm /* LZSS members */ 264231200Smm struct huffman_code maincode; 265231200Smm struct huffman_code offsetcode; 266231200Smm struct huffman_code lowoffsetcode; 267231200Smm struct huffman_code lengthcode; 268231200Smm unsigned char lengthtable[HUFFMAN_TABLE_SIZE]; 269231200Smm struct lzss lzss; 270231200Smm char output_last_match; 271231200Smm unsigned int lastlength; 272231200Smm unsigned int lastoffset; 273231200Smm unsigned int oldoffset[4]; 274231200Smm unsigned int lastlowoffset; 275231200Smm unsigned int numlowoffsetrepeats; 276231200Smm int64_t filterstart; 277231200Smm char start_new_table; 278231200Smm 279231200Smm /* PPMd Variant H members */ 280231200Smm char ppmd_valid; 281231200Smm char ppmd_eod; 282231200Smm char is_ppmd_block; 283231200Smm int ppmd_escape; 284231200Smm CPpmd7 ppmd7_context; 285231200Smm CPpmd7z_RangeDec range_dec; 286231200Smm IByteIn bytein; 287231200Smm 288231200Smm /* 289231200Smm * String conversion object. 290231200Smm */ 291231200Smm int init_default_conversion; 292231200Smm struct archive_string_conv *sconv_default; 293231200Smm struct archive_string_conv *opt_sconv; 294231200Smm struct archive_string_conv *sconv_utf8; 295231200Smm struct archive_string_conv *sconv_utf16be; 296231200Smm 297231200Smm /* 298231200Smm * Bit stream reader. 299231200Smm */ 300231200Smm struct rar_br { 301231200Smm#define CACHE_TYPE uint64_t 302231200Smm#define CACHE_BITS (8 * sizeof(CACHE_TYPE)) 303231200Smm /* Cache buffer. */ 304231200Smm CACHE_TYPE cache_buffer; 305231200Smm /* Indicates how many bits avail in cache_buffer. */ 306231200Smm int cache_avail; 307231200Smm ssize_t avail_in; 308231200Smm const unsigned char *next_in; 309231200Smm } br; 310299529Smm 311299529Smm /* 312299529Smm * Custom field to denote that this archive contains encrypted entries 313299529Smm */ 314299529Smm int has_encrypted_entries; 315231200Smm}; 316231200Smm 317299529Smmstatic int archive_read_support_format_rar_capabilities(struct archive_read *); 318299529Smmstatic int archive_read_format_rar_has_encrypted_entries(struct archive_read *); 319231200Smmstatic int archive_read_format_rar_bid(struct archive_read *, int); 320231200Smmstatic int archive_read_format_rar_options(struct archive_read *, 321231200Smm const char *, const char *); 322231200Smmstatic int archive_read_format_rar_read_header(struct archive_read *, 323231200Smm struct archive_entry *); 324231200Smmstatic int archive_read_format_rar_read_data(struct archive_read *, 325231200Smm const void **, size_t *, int64_t *); 326231200Smmstatic int archive_read_format_rar_read_data_skip(struct archive_read *a); 327248616Smmstatic int64_t archive_read_format_rar_seek_data(struct archive_read *, int64_t, 328248616Smm int); 329231200Smmstatic int archive_read_format_rar_cleanup(struct archive_read *); 330231200Smm 331231200Smm/* Support functions */ 332231200Smmstatic int read_header(struct archive_read *, struct archive_entry *, char); 333232153Smmstatic time_t get_time(int); 334231200Smmstatic int read_exttime(const char *, struct rar *, const char *); 335231200Smmstatic int read_symlink_stored(struct archive_read *, struct archive_entry *, 336231200Smm struct archive_string_conv *); 337231200Smmstatic int read_data_stored(struct archive_read *, const void **, size_t *, 338231200Smm int64_t *); 339231200Smmstatic int read_data_compressed(struct archive_read *, const void **, size_t *, 340231200Smm int64_t *); 341231200Smmstatic int rar_br_preparation(struct archive_read *, struct rar_br *); 342231200Smmstatic int parse_codes(struct archive_read *); 343231200Smmstatic void free_codes(struct archive_read *); 344231200Smmstatic int read_next_symbol(struct archive_read *, struct huffman_code *); 345231200Smmstatic int create_code(struct archive_read *, struct huffman_code *, 346231200Smm unsigned char *, int, char); 347231200Smmstatic int add_value(struct archive_read *, struct huffman_code *, int, int, 348231200Smm int); 349231200Smmstatic int new_node(struct huffman_code *); 350231200Smmstatic int make_table(struct archive_read *, struct huffman_code *); 351231200Smmstatic int make_table_recurse(struct archive_read *, struct huffman_code *, int, 352231200Smm struct huffman_table_entry *, int, int); 353231200Smmstatic int64_t expand(struct archive_read *, int64_t); 354231200Smmstatic int copy_from_lzss_window(struct archive_read *, const void **, 355231200Smm int64_t, int); 356248616Smmstatic const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *); 357231200Smm 358231200Smm/* 359231200Smm * Bit stream reader. 360231200Smm */ 361231200Smm/* Check that the cache buffer has enough bits. */ 362231200Smm#define rar_br_has(br, n) ((br)->cache_avail >= n) 363231200Smm/* Get compressed data by bit. */ 364231200Smm#define rar_br_bits(br, n) \ 365231200Smm (((uint32_t)((br)->cache_buffer >> \ 366231200Smm ((br)->cache_avail - (n)))) & cache_masks[n]) 367231200Smm#define rar_br_bits_forced(br, n) \ 368231200Smm (((uint32_t)((br)->cache_buffer << \ 369231200Smm ((n) - (br)->cache_avail))) & cache_masks[n]) 370231200Smm/* Read ahead to make sure the cache buffer has enough compressed data we 371231200Smm * will use. 372231200Smm * True : completed, there is enough data in the cache buffer. 373231200Smm * False : there is no data in the stream. */ 374231200Smm#define rar_br_read_ahead(a, br, n) \ 375231200Smm ((rar_br_has(br, (n)) || rar_br_fillup(a, br)) || rar_br_has(br, (n))) 376231200Smm/* Notify how many bits we consumed. */ 377231200Smm#define rar_br_consume(br, n) ((br)->cache_avail -= (n)) 378231200Smm#define rar_br_consume_unalined_bits(br) ((br)->cache_avail &= ~7) 379231200Smm 380231200Smmstatic const uint32_t cache_masks[] = { 381231200Smm 0x00000000, 0x00000001, 0x00000003, 0x00000007, 382231200Smm 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, 383231200Smm 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 384231200Smm 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 385231200Smm 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 386231200Smm 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 387231200Smm 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 388231200Smm 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 389231200Smm 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF 390231200Smm}; 391231200Smm 392231200Smm/* 393231200Smm * Shift away used bits in the cache data and fill it up with following bits. 394231200Smm * Call this when cache buffer does not have enough bits you need. 395231200Smm * 396231200Smm * Returns 1 if the cache buffer is full. 397231200Smm * Returns 0 if the cache buffer is not full; input buffer is empty. 398231200Smm */ 399231200Smmstatic int 400231200Smmrar_br_fillup(struct archive_read *a, struct rar_br *br) 401231200Smm{ 402231200Smm struct rar *rar = (struct rar *)(a->format->data); 403231200Smm int n = CACHE_BITS - br->cache_avail; 404231200Smm 405231200Smm for (;;) { 406231200Smm switch (n >> 3) { 407231200Smm case 8: 408231200Smm if (br->avail_in >= 8) { 409231200Smm br->cache_buffer = 410231200Smm ((uint64_t)br->next_in[0]) << 56 | 411231200Smm ((uint64_t)br->next_in[1]) << 48 | 412231200Smm ((uint64_t)br->next_in[2]) << 40 | 413231200Smm ((uint64_t)br->next_in[3]) << 32 | 414231200Smm ((uint32_t)br->next_in[4]) << 24 | 415231200Smm ((uint32_t)br->next_in[5]) << 16 | 416231200Smm ((uint32_t)br->next_in[6]) << 8 | 417231200Smm (uint32_t)br->next_in[7]; 418231200Smm br->next_in += 8; 419231200Smm br->avail_in -= 8; 420231200Smm br->cache_avail += 8 * 8; 421231200Smm rar->bytes_unconsumed += 8; 422231200Smm rar->bytes_remaining -= 8; 423231200Smm return (1); 424231200Smm } 425231200Smm break; 426231200Smm case 7: 427231200Smm if (br->avail_in >= 7) { 428231200Smm br->cache_buffer = 429231200Smm (br->cache_buffer << 56) | 430231200Smm ((uint64_t)br->next_in[0]) << 48 | 431231200Smm ((uint64_t)br->next_in[1]) << 40 | 432231200Smm ((uint64_t)br->next_in[2]) << 32 | 433231200Smm ((uint32_t)br->next_in[3]) << 24 | 434231200Smm ((uint32_t)br->next_in[4]) << 16 | 435231200Smm ((uint32_t)br->next_in[5]) << 8 | 436231200Smm (uint32_t)br->next_in[6]; 437231200Smm br->next_in += 7; 438231200Smm br->avail_in -= 7; 439231200Smm br->cache_avail += 7 * 8; 440231200Smm rar->bytes_unconsumed += 7; 441231200Smm rar->bytes_remaining -= 7; 442231200Smm return (1); 443231200Smm } 444231200Smm break; 445231200Smm case 6: 446231200Smm if (br->avail_in >= 6) { 447231200Smm br->cache_buffer = 448231200Smm (br->cache_buffer << 48) | 449231200Smm ((uint64_t)br->next_in[0]) << 40 | 450231200Smm ((uint64_t)br->next_in[1]) << 32 | 451231200Smm ((uint32_t)br->next_in[2]) << 24 | 452231200Smm ((uint32_t)br->next_in[3]) << 16 | 453231200Smm ((uint32_t)br->next_in[4]) << 8 | 454231200Smm (uint32_t)br->next_in[5]; 455231200Smm br->next_in += 6; 456231200Smm br->avail_in -= 6; 457231200Smm br->cache_avail += 6 * 8; 458231200Smm rar->bytes_unconsumed += 6; 459231200Smm rar->bytes_remaining -= 6; 460231200Smm return (1); 461231200Smm } 462231200Smm break; 463231200Smm case 0: 464231200Smm /* We have enough compressed data in 465231200Smm * the cache buffer.*/ 466231200Smm return (1); 467231200Smm default: 468231200Smm break; 469231200Smm } 470231200Smm if (br->avail_in <= 0) { 471231200Smm 472231200Smm if (rar->bytes_unconsumed > 0) { 473231200Smm /* Consume as much as the decompressor 474231200Smm * actually used. */ 475231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 476231200Smm rar->bytes_unconsumed = 0; 477231200Smm } 478248616Smm br->next_in = rar_read_ahead(a, 1, &(br->avail_in)); 479231200Smm if (br->next_in == NULL) 480231200Smm return (0); 481231200Smm if (br->avail_in == 0) 482231200Smm return (0); 483231200Smm } 484231200Smm br->cache_buffer = 485231200Smm (br->cache_buffer << 8) | *br->next_in++; 486231200Smm br->avail_in--; 487231200Smm br->cache_avail += 8; 488231200Smm n -= 8; 489231200Smm rar->bytes_unconsumed++; 490231200Smm rar->bytes_remaining--; 491231200Smm } 492231200Smm} 493231200Smm 494231200Smmstatic int 495231200Smmrar_br_preparation(struct archive_read *a, struct rar_br *br) 496231200Smm{ 497231200Smm struct rar *rar = (struct rar *)(a->format->data); 498231200Smm 499231200Smm if (rar->bytes_remaining > 0) { 500248616Smm br->next_in = rar_read_ahead(a, 1, &(br->avail_in)); 501231200Smm if (br->next_in == NULL) { 502231200Smm archive_set_error(&a->archive, 503231200Smm ARCHIVE_ERRNO_FILE_FORMAT, 504231200Smm "Truncated RAR file data"); 505231200Smm return (ARCHIVE_FATAL); 506231200Smm } 507231200Smm if (br->cache_avail == 0) 508231200Smm (void)rar_br_fillup(a, br); 509231200Smm } 510231200Smm return (ARCHIVE_OK); 511231200Smm} 512231200Smm 513231200Smm/* Find last bit set */ 514231200Smmstatic inline int 515231200Smmrar_fls(unsigned int word) 516231200Smm{ 517231200Smm word |= (word >> 1); 518231200Smm word |= (word >> 2); 519231200Smm word |= (word >> 4); 520231200Smm word |= (word >> 8); 521231200Smm word |= (word >> 16); 522231200Smm return word - (word >> 1); 523231200Smm} 524231200Smm 525231200Smm/* LZSS functions */ 526231200Smmstatic inline int64_t 527231200Smmlzss_position(struct lzss *lzss) 528231200Smm{ 529231200Smm return lzss->position; 530231200Smm} 531231200Smm 532231200Smmstatic inline int 533231200Smmlzss_mask(struct lzss *lzss) 534231200Smm{ 535231200Smm return lzss->mask; 536231200Smm} 537231200Smm 538231200Smmstatic inline int 539231200Smmlzss_size(struct lzss *lzss) 540231200Smm{ 541231200Smm return lzss->mask + 1; 542231200Smm} 543231200Smm 544231200Smmstatic inline int 545231200Smmlzss_offset_for_position(struct lzss *lzss, int64_t pos) 546231200Smm{ 547238856Smm return (int)(pos & lzss->mask); 548231200Smm} 549231200Smm 550231200Smmstatic inline unsigned char * 551231200Smmlzss_pointer_for_position(struct lzss *lzss, int64_t pos) 552231200Smm{ 553231200Smm return &lzss->window[lzss_offset_for_position(lzss, pos)]; 554231200Smm} 555231200Smm 556231200Smmstatic inline int 557231200Smmlzss_current_offset(struct lzss *lzss) 558231200Smm{ 559231200Smm return lzss_offset_for_position(lzss, lzss->position); 560231200Smm} 561231200Smm 562231200Smmstatic inline uint8_t * 563231200Smmlzss_current_pointer(struct lzss *lzss) 564231200Smm{ 565231200Smm return lzss_pointer_for_position(lzss, lzss->position); 566231200Smm} 567231200Smm 568231200Smmstatic inline void 569231200Smmlzss_emit_literal(struct rar *rar, uint8_t literal) 570231200Smm{ 571231200Smm *lzss_current_pointer(&rar->lzss) = literal; 572231200Smm rar->lzss.position++; 573231200Smm} 574231200Smm 575231200Smmstatic inline void 576231200Smmlzss_emit_match(struct rar *rar, int offset, int length) 577231200Smm{ 578231200Smm int dstoffs = lzss_current_offset(&rar->lzss); 579231200Smm int srcoffs = (dstoffs - offset) & lzss_mask(&rar->lzss); 580231200Smm int l, li, remaining; 581231200Smm unsigned char *d, *s; 582231200Smm 583231200Smm remaining = length; 584231200Smm while (remaining > 0) { 585231200Smm l = remaining; 586231200Smm if (dstoffs > srcoffs) { 587231200Smm if (l > lzss_size(&rar->lzss) - dstoffs) 588231200Smm l = lzss_size(&rar->lzss) - dstoffs; 589231200Smm } else { 590231200Smm if (l > lzss_size(&rar->lzss) - srcoffs) 591231200Smm l = lzss_size(&rar->lzss) - srcoffs; 592231200Smm } 593231200Smm d = &(rar->lzss.window[dstoffs]); 594231200Smm s = &(rar->lzss.window[srcoffs]); 595231200Smm if ((dstoffs + l < srcoffs) || (srcoffs + l < dstoffs)) 596231200Smm memcpy(d, s, l); 597231200Smm else { 598231200Smm for (li = 0; li < l; li++) 599231200Smm d[li] = s[li]; 600231200Smm } 601231200Smm remaining -= l; 602231200Smm dstoffs = (dstoffs + l) & lzss_mask(&(rar->lzss)); 603231200Smm srcoffs = (srcoffs + l) & lzss_mask(&(rar->lzss)); 604231200Smm } 605231200Smm rar->lzss.position += length; 606231200Smm} 607231200Smm 608231200Smmstatic Byte 609231200Smmppmd_read(void *p) 610231200Smm{ 611231200Smm struct archive_read *a = ((IByteIn*)p)->a; 612231200Smm struct rar *rar = (struct rar *)(a->format->data); 613231200Smm struct rar_br *br = &(rar->br); 614231200Smm Byte b; 615231200Smm if (!rar_br_read_ahead(a, br, 8)) 616231200Smm { 617231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 618231200Smm "Truncated RAR file data"); 619231200Smm rar->valid = 0; 620231200Smm return 0; 621231200Smm } 622231200Smm b = rar_br_bits(br, 8); 623231200Smm rar_br_consume(br, 8); 624231200Smm return b; 625231200Smm} 626231200Smm 627231200Smmint 628231200Smmarchive_read_support_format_rar(struct archive *_a) 629231200Smm{ 630231200Smm struct archive_read *a = (struct archive_read *)_a; 631231200Smm struct rar *rar; 632231200Smm int r; 633231200Smm 634231200Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 635231200Smm "archive_read_support_format_rar"); 636231200Smm 637311041Smm rar = (struct rar *)calloc(sizeof(*rar), 1); 638231200Smm if (rar == NULL) 639231200Smm { 640231200Smm archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data"); 641231200Smm return (ARCHIVE_FATAL); 642231200Smm } 643231200Smm 644299529Smm /* 645299529Smm * Until enough data has been read, we cannot tell about 646299529Smm * any encrypted entries yet. 647299529Smm */ 648299529Smm rar->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; 649299529Smm 650231200Smm r = __archive_read_register_format(a, 651231200Smm rar, 652231200Smm "rar", 653231200Smm archive_read_format_rar_bid, 654231200Smm archive_read_format_rar_options, 655231200Smm archive_read_format_rar_read_header, 656231200Smm archive_read_format_rar_read_data, 657231200Smm archive_read_format_rar_read_data_skip, 658248616Smm archive_read_format_rar_seek_data, 659299529Smm archive_read_format_rar_cleanup, 660299529Smm archive_read_support_format_rar_capabilities, 661299529Smm archive_read_format_rar_has_encrypted_entries); 662231200Smm 663231200Smm if (r != ARCHIVE_OK) 664231200Smm free(rar); 665231200Smm return (r); 666231200Smm} 667231200Smm 668231200Smmstatic int 669299529Smmarchive_read_support_format_rar_capabilities(struct archive_read * a) 670299529Smm{ 671299529Smm (void)a; /* UNUSED */ 672299529Smm return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA 673299529Smm | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA); 674299529Smm} 675299529Smm 676299529Smmstatic int 677299529Smmarchive_read_format_rar_has_encrypted_entries(struct archive_read *_a) 678299529Smm{ 679299529Smm if (_a && _a->format) { 680299529Smm struct rar * rar = (struct rar *)_a->format->data; 681299529Smm if (rar) { 682299529Smm return rar->has_encrypted_entries; 683299529Smm } 684299529Smm } 685299529Smm return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; 686299529Smm} 687299529Smm 688299529Smm 689299529Smmstatic int 690231200Smmarchive_read_format_rar_bid(struct archive_read *a, int best_bid) 691231200Smm{ 692231200Smm const char *p; 693231200Smm 694231200Smm /* If there's already a bid > 30, we'll never win. */ 695231200Smm if (best_bid > 30) 696231200Smm return (-1); 697231200Smm 698231200Smm if ((p = __archive_read_ahead(a, 7, NULL)) == NULL) 699231200Smm return (-1); 700231200Smm 701231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) 702231200Smm return (30); 703231200Smm 704231200Smm if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) { 705231200Smm /* This is a PE file */ 706231200Smm ssize_t offset = 0x10000; 707231200Smm ssize_t window = 4096; 708231200Smm ssize_t bytes_avail; 709231200Smm while (offset + window <= (1024 * 128)) { 710231200Smm const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail); 711231200Smm if (buff == NULL) { 712231200Smm /* Remaining bytes are less than window. */ 713231200Smm window >>= 1; 714231200Smm if (window < 0x40) 715231200Smm return (0); 716231200Smm continue; 717231200Smm } 718231200Smm p = buff + offset; 719231200Smm while (p + 7 < buff + bytes_avail) { 720231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) 721231200Smm return (30); 722231200Smm p += 0x10; 723231200Smm } 724231200Smm offset = p - buff; 725231200Smm } 726231200Smm } 727231200Smm return (0); 728231200Smm} 729231200Smm 730231200Smmstatic int 731231200Smmskip_sfx(struct archive_read *a) 732231200Smm{ 733231200Smm const void *h; 734231200Smm const char *p, *q; 735231200Smm size_t skip, total; 736231200Smm ssize_t bytes, window; 737231200Smm 738231200Smm total = 0; 739231200Smm window = 4096; 740231200Smm while (total + window <= (1024 * 128)) { 741231200Smm h = __archive_read_ahead(a, window, &bytes); 742231200Smm if (h == NULL) { 743231200Smm /* Remaining bytes are less than window. */ 744231200Smm window >>= 1; 745231200Smm if (window < 0x40) 746231200Smm goto fatal; 747231200Smm continue; 748231200Smm } 749231200Smm if (bytes < 0x40) 750231200Smm goto fatal; 751231200Smm p = h; 752231200Smm q = p + bytes; 753231200Smm 754231200Smm /* 755231200Smm * Scan ahead until we find something that looks 756231200Smm * like the RAR header. 757231200Smm */ 758231200Smm while (p + 7 < q) { 759231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) { 760231200Smm skip = p - (const char *)h; 761231200Smm __archive_read_consume(a, skip); 762231200Smm return (ARCHIVE_OK); 763231200Smm } 764231200Smm p += 0x10; 765231200Smm } 766231200Smm skip = p - (const char *)h; 767231200Smm __archive_read_consume(a, skip); 768231200Smm total += skip; 769231200Smm } 770231200Smmfatal: 771231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 772231200Smm "Couldn't find out RAR header"); 773231200Smm return (ARCHIVE_FATAL); 774231200Smm} 775231200Smm 776231200Smmstatic int 777231200Smmarchive_read_format_rar_options(struct archive_read *a, 778231200Smm const char *key, const char *val) 779231200Smm{ 780231200Smm struct rar *rar; 781231200Smm int ret = ARCHIVE_FAILED; 782299529Smm 783231200Smm rar = (struct rar *)(a->format->data); 784231200Smm if (strcmp(key, "hdrcharset") == 0) { 785231200Smm if (val == NULL || val[0] == 0) 786231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 787231200Smm "rar: hdrcharset option needs a character-set name"); 788231200Smm else { 789231200Smm rar->opt_sconv = 790231200Smm archive_string_conversion_from_charset( 791231200Smm &a->archive, val, 0); 792231200Smm if (rar->opt_sconv != NULL) 793231200Smm ret = ARCHIVE_OK; 794231200Smm else 795231200Smm ret = ARCHIVE_FATAL; 796231200Smm } 797232153Smm return (ret); 798232153Smm } 799232153Smm 800232153Smm /* Note: The "warn" return is just to inform the options 801232153Smm * supervisor that we didn't handle it. It will generate 802232153Smm * a suitable error if no one used this option. */ 803232153Smm return (ARCHIVE_WARN); 804231200Smm} 805231200Smm 806231200Smmstatic int 807231200Smmarchive_read_format_rar_read_header(struct archive_read *a, 808231200Smm struct archive_entry *entry) 809231200Smm{ 810231200Smm const void *h; 811231200Smm const char *p; 812231200Smm struct rar *rar; 813231200Smm size_t skip; 814231200Smm char head_type; 815231200Smm int ret; 816231200Smm unsigned flags; 817299529Smm unsigned long crc32_expected; 818231200Smm 819231200Smm a->archive.archive_format = ARCHIVE_FORMAT_RAR; 820231200Smm if (a->archive.archive_format_name == NULL) 821231200Smm a->archive.archive_format_name = "RAR"; 822231200Smm 823231200Smm rar = (struct rar *)(a->format->data); 824231200Smm 825299529Smm /* 826299529Smm * It should be sufficient to call archive_read_next_header() for 827299529Smm * a reader to determine if an entry is encrypted or not. If the 828299529Smm * encryption of an entry is only detectable when calling 829299529Smm * archive_read_data(), so be it. We'll do the same check there 830299529Smm * as well. 831299529Smm */ 832299529Smm if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { 833299529Smm rar->has_encrypted_entries = 0; 834299529Smm } 835299529Smm 836231200Smm /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if 837231200Smm * this fails. 838231200Smm */ 839231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 840231200Smm return (ARCHIVE_EOF); 841231200Smm 842231200Smm p = h; 843231200Smm if (rar->found_first_header == 0 && 844231200Smm ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) { 845231200Smm /* This is an executable ? Must be self-extracting... */ 846231200Smm ret = skip_sfx(a); 847231200Smm if (ret < ARCHIVE_WARN) 848231200Smm return (ret); 849231200Smm } 850231200Smm rar->found_first_header = 1; 851231200Smm 852231200Smm while (1) 853231200Smm { 854231200Smm unsigned long crc32_val; 855231200Smm 856231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 857231200Smm return (ARCHIVE_FATAL); 858231200Smm p = h; 859231200Smm 860231200Smm head_type = p[2]; 861231200Smm switch(head_type) 862231200Smm { 863231200Smm case MARK_HEAD: 864231200Smm if (memcmp(p, RAR_SIGNATURE, 7) != 0) { 865231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 866231200Smm "Invalid marker header"); 867231200Smm return (ARCHIVE_FATAL); 868231200Smm } 869231200Smm __archive_read_consume(a, 7); 870231200Smm break; 871231200Smm 872231200Smm case MAIN_HEAD: 873231200Smm rar->main_flags = archive_le16dec(p + 3); 874231200Smm skip = archive_le16dec(p + 5); 875231200Smm if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) { 876231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 877231200Smm "Invalid header size"); 878231200Smm return (ARCHIVE_FATAL); 879231200Smm } 880231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 881231200Smm return (ARCHIVE_FATAL); 882231200Smm p = h; 883231200Smm memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1)); 884231200Smm memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1), 885231200Smm sizeof(rar->reserved2)); 886231200Smm if (rar->main_flags & MHD_ENCRYPTVER) { 887231200Smm if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) { 888231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 889231200Smm "Invalid header size"); 890231200Smm return (ARCHIVE_FATAL); 891231200Smm } 892231200Smm rar->encryptver = *(p + 7 + sizeof(rar->reserved1) + 893231200Smm sizeof(rar->reserved2)); 894231200Smm } 895231200Smm 896313570Smm /* Main header is password encrypted, so we cannot read any 897299529Smm file names or any other info about files from the header. */ 898231200Smm if (rar->main_flags & MHD_PASSWORD) 899231200Smm { 900299529Smm archive_entry_set_is_metadata_encrypted(entry, 1); 901299529Smm archive_entry_set_is_data_encrypted(entry, 1); 902299529Smm rar->has_encrypted_entries = 1; 903299529Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 904231200Smm "RAR encryption support unavailable."); 905231200Smm return (ARCHIVE_FATAL); 906231200Smm } 907231200Smm 908248616Smm crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2); 909231200Smm if ((crc32_val & 0xffff) != archive_le16dec(p)) { 910231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 911231200Smm "Header CRC error"); 912231200Smm return (ARCHIVE_FATAL); 913231200Smm } 914231200Smm __archive_read_consume(a, skip); 915231200Smm break; 916231200Smm 917231200Smm case FILE_HEAD: 918231200Smm return read_header(a, entry, head_type); 919231200Smm 920231200Smm case COMM_HEAD: 921231200Smm case AV_HEAD: 922231200Smm case SUB_HEAD: 923231200Smm case PROTECT_HEAD: 924231200Smm case SIGN_HEAD: 925248616Smm case ENDARC_HEAD: 926231200Smm flags = archive_le16dec(p + 3); 927231200Smm skip = archive_le16dec(p + 5); 928231200Smm if (skip < 7) { 929231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 930299529Smm "Invalid header size too small"); 931231200Smm return (ARCHIVE_FATAL); 932231200Smm } 933231200Smm if (flags & HD_ADD_SIZE_PRESENT) 934231200Smm { 935231200Smm if (skip < 7 + 4) { 936231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 937299529Smm "Invalid header size too small"); 938231200Smm return (ARCHIVE_FATAL); 939231200Smm } 940231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 941231200Smm return (ARCHIVE_FATAL); 942231200Smm p = h; 943299529Smm skip += archive_le32dec(p + 7); 944231200Smm } 945231200Smm 946299529Smm /* Skip over the 2-byte CRC at the beginning of the header. */ 947299529Smm crc32_expected = archive_le16dec(p); 948299529Smm __archive_read_consume(a, 2); 949299529Smm skip -= 2; 950299529Smm 951299529Smm /* Skim the entire header and compute the CRC. */ 952299529Smm crc32_val = 0; 953299529Smm while (skip > 0) { 954299529Smm size_t to_read = skip; 955299529Smm ssize_t did_read; 956299529Smm if (to_read > 32 * 1024) { 957299529Smm to_read = 32 * 1024; 958299529Smm } 959299529Smm if ((h = __archive_read_ahead(a, to_read, &did_read)) == NULL) { 960299529Smm return (ARCHIVE_FATAL); 961299529Smm } 962299529Smm p = h; 963299529Smm crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned)did_read); 964299529Smm __archive_read_consume(a, did_read); 965299529Smm skip -= did_read; 966231200Smm } 967299529Smm if ((crc32_val & 0xffff) != crc32_expected) { 968299529Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 969299529Smm "Header CRC error"); 970299529Smm return (ARCHIVE_FATAL); 971299529Smm } 972248616Smm if (head_type == ENDARC_HEAD) 973299529Smm return (ARCHIVE_EOF); 974231200Smm break; 975231200Smm 976231200Smm case NEWSUB_HEAD: 977231200Smm if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN) 978231200Smm return ret; 979231200Smm break; 980231200Smm 981231200Smm default: 982231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 983231200Smm "Bad RAR file"); 984231200Smm return (ARCHIVE_FATAL); 985231200Smm } 986231200Smm } 987231200Smm} 988231200Smm 989231200Smmstatic int 990231200Smmarchive_read_format_rar_read_data(struct archive_read *a, const void **buff, 991231200Smm size_t *size, int64_t *offset) 992231200Smm{ 993231200Smm struct rar *rar = (struct rar *)(a->format->data); 994231200Smm int ret; 995231200Smm 996299529Smm if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { 997299529Smm rar->has_encrypted_entries = 0; 998299529Smm } 999299529Smm 1000231200Smm if (rar->bytes_unconsumed > 0) { 1001231200Smm /* Consume as much as the decompressor actually used. */ 1002231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 1003231200Smm rar->bytes_unconsumed = 0; 1004231200Smm } 1005231200Smm 1006299529Smm *buff = NULL; 1007248616Smm if (rar->entry_eof || rar->offset_seek >= rar->unp_size) { 1008231200Smm *size = 0; 1009231200Smm *offset = rar->offset; 1010248616Smm if (*offset < rar->unp_size) 1011248616Smm *offset = rar->unp_size; 1012231200Smm return (ARCHIVE_EOF); 1013231200Smm } 1014231200Smm 1015231200Smm switch (rar->compression_method) 1016231200Smm { 1017231200Smm case COMPRESS_METHOD_STORE: 1018231200Smm ret = read_data_stored(a, buff, size, offset); 1019299529Smm break; 1020231200Smm 1021231200Smm case COMPRESS_METHOD_FASTEST: 1022231200Smm case COMPRESS_METHOD_FAST: 1023231200Smm case COMPRESS_METHOD_NORMAL: 1024231200Smm case COMPRESS_METHOD_GOOD: 1025231200Smm case COMPRESS_METHOD_BEST: 1026231200Smm ret = read_data_compressed(a, buff, size, offset); 1027348607Smm if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) { 1028328827Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); 1029348607Smm rar->start_new_table = 1; 1030348607Smm } 1031299529Smm break; 1032231200Smm 1033231200Smm default: 1034231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1035231200Smm "Unsupported compression method for RAR file."); 1036231200Smm ret = ARCHIVE_FATAL; 1037299529Smm break; 1038231200Smm } 1039231200Smm return (ret); 1040231200Smm} 1041231200Smm 1042231200Smmstatic int 1043231200Smmarchive_read_format_rar_read_data_skip(struct archive_read *a) 1044231200Smm{ 1045231200Smm struct rar *rar; 1046231200Smm int64_t bytes_skipped; 1047248616Smm int ret; 1048231200Smm 1049231200Smm rar = (struct rar *)(a->format->data); 1050231200Smm 1051231200Smm if (rar->bytes_unconsumed > 0) { 1052231200Smm /* Consume as much as the decompressor actually used. */ 1053231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 1054231200Smm rar->bytes_unconsumed = 0; 1055231200Smm } 1056231200Smm 1057231200Smm if (rar->bytes_remaining > 0) { 1058231200Smm bytes_skipped = __archive_read_consume(a, rar->bytes_remaining); 1059231200Smm if (bytes_skipped < 0) 1060231200Smm return (ARCHIVE_FATAL); 1061231200Smm } 1062248616Smm 1063248616Smm /* Compressed data to skip must be read from each header in a multivolume 1064248616Smm * archive. 1065248616Smm */ 1066248616Smm if (rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER) 1067248616Smm { 1068248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1069248616Smm if (ret == (ARCHIVE_EOF)) 1070248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1071248616Smm if (ret != (ARCHIVE_OK)) 1072248616Smm return ret; 1073248616Smm return archive_read_format_rar_read_data_skip(a); 1074248616Smm } 1075248616Smm 1076231200Smm return (ARCHIVE_OK); 1077231200Smm} 1078231200Smm 1079248616Smmstatic int64_t 1080248616Smmarchive_read_format_rar_seek_data(struct archive_read *a, int64_t offset, 1081248616Smm int whence) 1082248616Smm{ 1083248616Smm int64_t client_offset, ret; 1084248616Smm unsigned int i; 1085248616Smm struct rar *rar = (struct rar *)(a->format->data); 1086248616Smm 1087248616Smm if (rar->compression_method == COMPRESS_METHOD_STORE) 1088248616Smm { 1089248616Smm /* Modify the offset for use with SEEK_SET */ 1090248616Smm switch (whence) 1091248616Smm { 1092248616Smm case SEEK_CUR: 1093248616Smm client_offset = rar->offset_seek; 1094248616Smm break; 1095248616Smm case SEEK_END: 1096248616Smm client_offset = rar->unp_size; 1097248616Smm break; 1098248616Smm case SEEK_SET: 1099248616Smm default: 1100248616Smm client_offset = 0; 1101248616Smm } 1102248616Smm client_offset += offset; 1103248616Smm if (client_offset < 0) 1104248616Smm { 1105248616Smm /* Can't seek past beginning of data block */ 1106248616Smm return -1; 1107248616Smm } 1108248616Smm else if (client_offset > rar->unp_size) 1109248616Smm { 1110248616Smm /* 1111248616Smm * Set the returned offset but only seek to the end of 1112248616Smm * the data block. 1113248616Smm */ 1114248616Smm rar->offset_seek = client_offset; 1115248616Smm client_offset = rar->unp_size; 1116248616Smm } 1117248616Smm 1118248616Smm client_offset += rar->dbo[0].start_offset; 1119248616Smm i = 0; 1120248616Smm while (i < rar->cursor) 1121248616Smm { 1122248616Smm i++; 1123248616Smm client_offset += rar->dbo[i].start_offset - rar->dbo[i-1].end_offset; 1124248616Smm } 1125248616Smm if (rar->main_flags & MHD_VOLUME) 1126248616Smm { 1127248616Smm /* Find the appropriate offset among the multivolume archive */ 1128248616Smm while (1) 1129248616Smm { 1130248616Smm if (client_offset < rar->dbo[rar->cursor].start_offset && 1131248616Smm rar->file_flags & FHD_SPLIT_BEFORE) 1132248616Smm { 1133248616Smm /* Search backwards for the correct data block */ 1134248616Smm if (rar->cursor == 0) 1135248616Smm { 1136248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1137248616Smm "Attempt to seek past beginning of RAR data block"); 1138248616Smm return (ARCHIVE_FAILED); 1139248616Smm } 1140248616Smm rar->cursor--; 1141248616Smm client_offset -= rar->dbo[rar->cursor+1].start_offset - 1142248616Smm rar->dbo[rar->cursor].end_offset; 1143248616Smm if (client_offset < rar->dbo[rar->cursor].start_offset) 1144248616Smm continue; 1145248616Smm ret = __archive_read_seek(a, rar->dbo[rar->cursor].start_offset - 1146248616Smm rar->dbo[rar->cursor].header_size, SEEK_SET); 1147248616Smm if (ret < (ARCHIVE_OK)) 1148248616Smm return ret; 1149248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1150248616Smm if (ret != (ARCHIVE_OK)) 1151248616Smm { 1152248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1153248616Smm "Error during seek of RAR file"); 1154248616Smm return (ARCHIVE_FAILED); 1155248616Smm } 1156248616Smm rar->cursor--; 1157248616Smm break; 1158248616Smm } 1159248616Smm else if (client_offset > rar->dbo[rar->cursor].end_offset && 1160248616Smm rar->file_flags & FHD_SPLIT_AFTER) 1161248616Smm { 1162248616Smm /* Search forward for the correct data block */ 1163248616Smm rar->cursor++; 1164248616Smm if (rar->cursor < rar->nodes && 1165248616Smm client_offset > rar->dbo[rar->cursor].end_offset) 1166248616Smm { 1167248616Smm client_offset += rar->dbo[rar->cursor].start_offset - 1168248616Smm rar->dbo[rar->cursor-1].end_offset; 1169248616Smm continue; 1170248616Smm } 1171248616Smm rar->cursor--; 1172248616Smm ret = __archive_read_seek(a, rar->dbo[rar->cursor].end_offset, 1173248616Smm SEEK_SET); 1174248616Smm if (ret < (ARCHIVE_OK)) 1175248616Smm return ret; 1176248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1177248616Smm if (ret == (ARCHIVE_EOF)) 1178248616Smm { 1179248616Smm rar->has_endarc_header = 1; 1180248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1181248616Smm } 1182248616Smm if (ret != (ARCHIVE_OK)) 1183248616Smm { 1184248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1185248616Smm "Error during seek of RAR file"); 1186248616Smm return (ARCHIVE_FAILED); 1187248616Smm } 1188248616Smm client_offset += rar->dbo[rar->cursor].start_offset - 1189248616Smm rar->dbo[rar->cursor-1].end_offset; 1190248616Smm continue; 1191248616Smm } 1192248616Smm break; 1193248616Smm } 1194248616Smm } 1195248616Smm 1196248616Smm ret = __archive_read_seek(a, client_offset, SEEK_SET); 1197248616Smm if (ret < (ARCHIVE_OK)) 1198248616Smm return ret; 1199248616Smm rar->bytes_remaining = rar->dbo[rar->cursor].end_offset - ret; 1200248616Smm i = rar->cursor; 1201248616Smm while (i > 0) 1202248616Smm { 1203248616Smm i--; 1204248616Smm ret -= rar->dbo[i+1].start_offset - rar->dbo[i].end_offset; 1205248616Smm } 1206248616Smm ret -= rar->dbo[0].start_offset; 1207248616Smm 1208248616Smm /* Always restart reading the file after a seek */ 1209299529Smm __archive_reset_read_data(&a->archive); 1210299529Smm 1211248616Smm rar->bytes_unconsumed = 0; 1212248616Smm rar->offset = 0; 1213248616Smm 1214248616Smm /* 1215248616Smm * If a seek past the end of file was requested, return the requested 1216248616Smm * offset. 1217248616Smm */ 1218248616Smm if (ret == rar->unp_size && rar->offset_seek > rar->unp_size) 1219248616Smm return rar->offset_seek; 1220248616Smm 1221248616Smm /* Return the new offset */ 1222248616Smm rar->offset_seek = ret; 1223248616Smm return rar->offset_seek; 1224248616Smm } 1225248616Smm else 1226248616Smm { 1227248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1228248616Smm "Seeking of compressed RAR files is unsupported"); 1229248616Smm } 1230248616Smm return (ARCHIVE_FAILED); 1231248616Smm} 1232248616Smm 1233231200Smmstatic int 1234231200Smmarchive_read_format_rar_cleanup(struct archive_read *a) 1235231200Smm{ 1236231200Smm struct rar *rar; 1237231200Smm 1238231200Smm rar = (struct rar *)(a->format->data); 1239231200Smm free_codes(a); 1240231200Smm free(rar->filename); 1241248616Smm free(rar->filename_save); 1242248616Smm free(rar->dbo); 1243231200Smm free(rar->unp_buffer); 1244231200Smm free(rar->lzss.window); 1245328827Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); 1246231200Smm free(rar); 1247231200Smm (a->format->data) = NULL; 1248231200Smm return (ARCHIVE_OK); 1249231200Smm} 1250231200Smm 1251231200Smmstatic int 1252231200Smmread_header(struct archive_read *a, struct archive_entry *entry, 1253231200Smm char head_type) 1254231200Smm{ 1255231200Smm const void *h; 1256231200Smm const char *p, *endp; 1257231200Smm struct rar *rar; 1258231200Smm struct rar_header rar_header; 1259231200Smm struct rar_file_header file_header; 1260231200Smm int64_t header_size; 1261231200Smm unsigned filename_size, end; 1262231200Smm char *filename; 1263231200Smm char *strp; 1264231200Smm char packed_size[8]; 1265231200Smm char unp_size[8]; 1266232153Smm int ttime; 1267231200Smm struct archive_string_conv *sconv, *fn_sconv; 1268231200Smm unsigned long crc32_val; 1269231200Smm int ret = (ARCHIVE_OK), ret2; 1270231200Smm 1271231200Smm rar = (struct rar *)(a->format->data); 1272231200Smm 1273231200Smm /* Setup a string conversion object for non-rar-unicode filenames. */ 1274231200Smm sconv = rar->opt_sconv; 1275231200Smm if (sconv == NULL) { 1276231200Smm if (!rar->init_default_conversion) { 1277231200Smm rar->sconv_default = 1278231200Smm archive_string_default_conversion_for_read( 1279231200Smm &(a->archive)); 1280231200Smm rar->init_default_conversion = 1; 1281231200Smm } 1282231200Smm sconv = rar->sconv_default; 1283231200Smm } 1284231200Smm 1285231200Smm 1286231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 1287231200Smm return (ARCHIVE_FATAL); 1288231200Smm p = h; 1289231200Smm memcpy(&rar_header, p, sizeof(rar_header)); 1290231200Smm rar->file_flags = archive_le16dec(rar_header.flags); 1291231200Smm header_size = archive_le16dec(rar_header.size); 1292232153Smm if (header_size < (int64_t)sizeof(file_header) + 7) { 1293231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1294231200Smm "Invalid header size"); 1295231200Smm return (ARCHIVE_FATAL); 1296231200Smm } 1297231200Smm crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2); 1298231200Smm __archive_read_consume(a, 7); 1299231200Smm 1300231200Smm if (!(rar->file_flags & FHD_SOLID)) 1301231200Smm { 1302231200Smm rar->compression_method = 0; 1303231200Smm rar->packed_size = 0; 1304231200Smm rar->unp_size = 0; 1305231200Smm rar->mtime = 0; 1306231200Smm rar->ctime = 0; 1307231200Smm rar->atime = 0; 1308231200Smm rar->arctime = 0; 1309231200Smm rar->mode = 0; 1310231200Smm memset(&rar->salt, 0, sizeof(rar->salt)); 1311231200Smm rar->atime = 0; 1312231200Smm rar->ansec = 0; 1313231200Smm rar->ctime = 0; 1314231200Smm rar->cnsec = 0; 1315231200Smm rar->mtime = 0; 1316231200Smm rar->mnsec = 0; 1317231200Smm rar->arctime = 0; 1318231200Smm rar->arcnsec = 0; 1319231200Smm } 1320231200Smm else 1321231200Smm { 1322231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1323231200Smm "RAR solid archive support unavailable."); 1324231200Smm return (ARCHIVE_FATAL); 1325231200Smm } 1326231200Smm 1327238856Smm if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL) 1328231200Smm return (ARCHIVE_FATAL); 1329231200Smm 1330231200Smm /* File Header CRC check. */ 1331238856Smm crc32_val = crc32(crc32_val, h, (unsigned)(header_size - 7)); 1332231200Smm if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) { 1333231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1334231200Smm "Header CRC error"); 1335231200Smm return (ARCHIVE_FATAL); 1336231200Smm } 1337231200Smm /* If no CRC error, Go on parsing File Header. */ 1338231200Smm p = h; 1339231200Smm endp = p + header_size - 7; 1340231200Smm memcpy(&file_header, p, sizeof(file_header)); 1341231200Smm p += sizeof(file_header); 1342231200Smm 1343231200Smm rar->compression_method = file_header.method; 1344231200Smm 1345232153Smm ttime = archive_le32dec(file_header.file_time); 1346232153Smm rar->mtime = get_time(ttime); 1347231200Smm 1348231200Smm rar->file_crc = archive_le32dec(file_header.file_crc); 1349231200Smm 1350231200Smm if (rar->file_flags & FHD_PASSWORD) 1351231200Smm { 1352299529Smm archive_entry_set_is_data_encrypted(entry, 1); 1353299529Smm rar->has_encrypted_entries = 1; 1354231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1355231200Smm "RAR encryption support unavailable."); 1356299529Smm /* Since it is only the data part itself that is encrypted we can at least 1357299529Smm extract information about the currently processed entry and don't need 1358299529Smm to return ARCHIVE_FATAL here. */ 1359299529Smm /*return (ARCHIVE_FATAL);*/ 1360231200Smm } 1361231200Smm 1362231200Smm if (rar->file_flags & FHD_LARGE) 1363231200Smm { 1364231200Smm memcpy(packed_size, file_header.pack_size, 4); 1365231200Smm memcpy(packed_size + 4, p, 4); /* High pack size */ 1366231200Smm p += 4; 1367231200Smm memcpy(unp_size, file_header.unp_size, 4); 1368231200Smm memcpy(unp_size + 4, p, 4); /* High unpack size */ 1369231200Smm p += 4; 1370231200Smm rar->packed_size = archive_le64dec(&packed_size); 1371231200Smm rar->unp_size = archive_le64dec(&unp_size); 1372231200Smm } 1373231200Smm else 1374231200Smm { 1375231200Smm rar->packed_size = archive_le32dec(file_header.pack_size); 1376231200Smm rar->unp_size = archive_le32dec(file_header.unp_size); 1377231200Smm } 1378231200Smm 1379231200Smm if (rar->packed_size < 0 || rar->unp_size < 0) 1380231200Smm { 1381231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1382231200Smm "Invalid sizes specified."); 1383231200Smm return (ARCHIVE_FATAL); 1384231200Smm } 1385231200Smm 1386248616Smm rar->bytes_remaining = rar->packed_size; 1387248616Smm 1388231200Smm /* TODO: RARv3 subblocks contain comments. For now the complete block is 1389231200Smm * consumed at the end. 1390231200Smm */ 1391231200Smm if (head_type == NEWSUB_HEAD) { 1392231200Smm size_t distance = p - (const char *)h; 1393231200Smm header_size += rar->packed_size; 1394231200Smm /* Make sure we have the extended data. */ 1395238856Smm if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL) 1396231200Smm return (ARCHIVE_FATAL); 1397231200Smm p = h; 1398231200Smm endp = p + header_size - 7; 1399231200Smm p += distance; 1400231200Smm } 1401231200Smm 1402231200Smm filename_size = archive_le16dec(file_header.name_size); 1403231200Smm if (p + filename_size > endp) { 1404231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1405231200Smm "Invalid filename size"); 1406231200Smm return (ARCHIVE_FATAL); 1407231200Smm } 1408238856Smm if (rar->filename_allocated < filename_size * 2 + 2) { 1409238856Smm char *newptr; 1410238856Smm size_t newsize = filename_size * 2 + 2; 1411238856Smm newptr = realloc(rar->filename, newsize); 1412238856Smm if (newptr == NULL) { 1413231200Smm archive_set_error(&a->archive, ENOMEM, 1414231200Smm "Couldn't allocate memory."); 1415231200Smm return (ARCHIVE_FATAL); 1416231200Smm } 1417238856Smm rar->filename = newptr; 1418238856Smm rar->filename_allocated = newsize; 1419231200Smm } 1420231200Smm filename = rar->filename; 1421231200Smm memcpy(filename, p, filename_size); 1422231200Smm filename[filename_size] = '\0'; 1423231200Smm if (rar->file_flags & FHD_UNICODE) 1424231200Smm { 1425231200Smm if (filename_size != strlen(filename)) 1426231200Smm { 1427248616Smm unsigned char highbyte, flagbits, flagbyte; 1428248616Smm unsigned fn_end, offset; 1429231200Smm 1430231200Smm end = filename_size; 1431238856Smm fn_end = filename_size * 2; 1432231200Smm filename_size = 0; 1433248616Smm offset = (unsigned)strlen(filename) + 1; 1434231200Smm highbyte = *(p + offset++); 1435231200Smm flagbits = 0; 1436231200Smm flagbyte = 0; 1437238856Smm while (offset < end && filename_size < fn_end) 1438231200Smm { 1439231200Smm if (!flagbits) 1440231200Smm { 1441231200Smm flagbyte = *(p + offset++); 1442231200Smm flagbits = 8; 1443231200Smm } 1444299529Smm 1445231200Smm flagbits -= 2; 1446231200Smm switch((flagbyte >> flagbits) & 3) 1447231200Smm { 1448231200Smm case 0: 1449231200Smm filename[filename_size++] = '\0'; 1450231200Smm filename[filename_size++] = *(p + offset++); 1451231200Smm break; 1452231200Smm case 1: 1453231200Smm filename[filename_size++] = highbyte; 1454231200Smm filename[filename_size++] = *(p + offset++); 1455231200Smm break; 1456231200Smm case 2: 1457231200Smm filename[filename_size++] = *(p + offset + 1); 1458231200Smm filename[filename_size++] = *(p + offset); 1459231200Smm offset += 2; 1460231200Smm break; 1461231200Smm case 3: 1462231200Smm { 1463238856Smm char extra, high; 1464238856Smm uint8_t length = *(p + offset++); 1465238856Smm 1466238856Smm if (length & 0x80) { 1467238856Smm extra = *(p + offset++); 1468238856Smm high = (char)highbyte; 1469238856Smm } else 1470238856Smm extra = high = 0; 1471238856Smm length = (length & 0x7f) + 2; 1472238856Smm while (length && filename_size < fn_end) { 1473238856Smm unsigned cp = filename_size >> 1; 1474238856Smm filename[filename_size++] = high; 1475238856Smm filename[filename_size++] = p[cp] + extra; 1476231200Smm length--; 1477231200Smm } 1478231200Smm } 1479231200Smm break; 1480231200Smm } 1481231200Smm } 1482238856Smm if (filename_size > fn_end) { 1483231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1484231200Smm "Invalid filename"); 1485231200Smm return (ARCHIVE_FATAL); 1486231200Smm } 1487231200Smm filename[filename_size++] = '\0'; 1488324417Smm /* 1489324417Smm * Do not increment filename_size here as the computations below 1490324417Smm * add the space for the terminating NUL explicitly. 1491324417Smm */ 1492324417Smm filename[filename_size] = '\0'; 1493231200Smm 1494231200Smm /* Decoded unicode form is UTF-16BE, so we have to update a string 1495231200Smm * conversion object for it. */ 1496231200Smm if (rar->sconv_utf16be == NULL) { 1497231200Smm rar->sconv_utf16be = archive_string_conversion_from_charset( 1498231200Smm &a->archive, "UTF-16BE", 1); 1499231200Smm if (rar->sconv_utf16be == NULL) 1500231200Smm return (ARCHIVE_FATAL); 1501231200Smm } 1502231200Smm fn_sconv = rar->sconv_utf16be; 1503231200Smm 1504231200Smm strp = filename; 1505231200Smm while (memcmp(strp, "\x00\x00", 2)) 1506231200Smm { 1507231200Smm if (!memcmp(strp, "\x00\\", 2)) 1508231200Smm *(strp + 1) = '/'; 1509231200Smm strp += 2; 1510231200Smm } 1511231200Smm p += offset; 1512231200Smm } else { 1513231200Smm /* 1514231200Smm * If FHD_UNICODE is set but no unicode data, this file name form 1515231200Smm * is UTF-8, so we have to update a string conversion object for 1516231200Smm * it accordingly. 1517231200Smm */ 1518231200Smm if (rar->sconv_utf8 == NULL) { 1519231200Smm rar->sconv_utf8 = archive_string_conversion_from_charset( 1520231200Smm &a->archive, "UTF-8", 1); 1521231200Smm if (rar->sconv_utf8 == NULL) 1522231200Smm return (ARCHIVE_FATAL); 1523231200Smm } 1524231200Smm fn_sconv = rar->sconv_utf8; 1525231200Smm while ((strp = strchr(filename, '\\')) != NULL) 1526231200Smm *strp = '/'; 1527231200Smm p += filename_size; 1528231200Smm } 1529231200Smm } 1530231200Smm else 1531231200Smm { 1532231200Smm fn_sconv = sconv; 1533231200Smm while ((strp = strchr(filename, '\\')) != NULL) 1534231200Smm *strp = '/'; 1535231200Smm p += filename_size; 1536231200Smm } 1537231200Smm 1538248616Smm /* Split file in multivolume RAR. No more need to process header. */ 1539248616Smm if (rar->filename_save && 1540299529Smm filename_size == rar->filename_save_size && 1541248616Smm !memcmp(rar->filename, rar->filename_save, filename_size + 1)) 1542248616Smm { 1543248616Smm __archive_read_consume(a, header_size - 7); 1544248616Smm rar->cursor++; 1545248616Smm if (rar->cursor >= rar->nodes) 1546248616Smm { 1547248616Smm rar->nodes++; 1548248616Smm if ((rar->dbo = 1549248616Smm realloc(rar->dbo, sizeof(*rar->dbo) * rar->nodes)) == NULL) 1550248616Smm { 1551248616Smm archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory."); 1552248616Smm return (ARCHIVE_FATAL); 1553248616Smm } 1554248616Smm rar->dbo[rar->cursor].header_size = header_size; 1555248616Smm rar->dbo[rar->cursor].start_offset = -1; 1556248616Smm rar->dbo[rar->cursor].end_offset = -1; 1557248616Smm } 1558248616Smm if (rar->dbo[rar->cursor].start_offset < 0) 1559248616Smm { 1560248616Smm rar->dbo[rar->cursor].start_offset = a->filter->position; 1561248616Smm rar->dbo[rar->cursor].end_offset = rar->dbo[rar->cursor].start_offset + 1562248616Smm rar->packed_size; 1563248616Smm } 1564248616Smm return ret; 1565248616Smm } 1566342360Smm else if (rar->filename_must_match) 1567342360Smm { 1568342360Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1569342360Smm "Mismatch of file parts split across multi-volume archive"); 1570342360Smm return (ARCHIVE_FATAL); 1571342360Smm } 1572248616Smm 1573248616Smm rar->filename_save = (char*)realloc(rar->filename_save, 1574248616Smm filename_size + 1); 1575248616Smm memcpy(rar->filename_save, rar->filename, filename_size + 1); 1576299529Smm rar->filename_save_size = filename_size; 1577248616Smm 1578248616Smm /* Set info for seeking */ 1579248616Smm free(rar->dbo); 1580248616Smm if ((rar->dbo = calloc(1, sizeof(*rar->dbo))) == NULL) 1581248616Smm { 1582248616Smm archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory."); 1583248616Smm return (ARCHIVE_FATAL); 1584248616Smm } 1585248616Smm rar->dbo[0].header_size = header_size; 1586248616Smm rar->dbo[0].start_offset = -1; 1587248616Smm rar->dbo[0].end_offset = -1; 1588248616Smm rar->cursor = 0; 1589248616Smm rar->nodes = 1; 1590248616Smm 1591231200Smm if (rar->file_flags & FHD_SALT) 1592231200Smm { 1593231200Smm if (p + 8 > endp) { 1594231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1595231200Smm "Invalid header size"); 1596231200Smm return (ARCHIVE_FATAL); 1597231200Smm } 1598231200Smm memcpy(rar->salt, p, 8); 1599231200Smm p += 8; 1600231200Smm } 1601231200Smm 1602231200Smm if (rar->file_flags & FHD_EXTTIME) { 1603231200Smm if (read_exttime(p, rar, endp) < 0) { 1604231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1605231200Smm "Invalid header size"); 1606231200Smm return (ARCHIVE_FATAL); 1607231200Smm } 1608231200Smm } 1609231200Smm 1610231200Smm __archive_read_consume(a, header_size - 7); 1611248616Smm rar->dbo[0].start_offset = a->filter->position; 1612248616Smm rar->dbo[0].end_offset = rar->dbo[0].start_offset + rar->packed_size; 1613231200Smm 1614231200Smm switch(file_header.host_os) 1615231200Smm { 1616231200Smm case OS_MSDOS: 1617231200Smm case OS_OS2: 1618231200Smm case OS_WIN32: 1619231200Smm rar->mode = archive_le32dec(file_header.file_attr); 1620231200Smm if (rar->mode & FILE_ATTRIBUTE_DIRECTORY) 1621231200Smm rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; 1622231200Smm else 1623231200Smm rar->mode = AE_IFREG; 1624231200Smm rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 1625231200Smm break; 1626231200Smm 1627231200Smm case OS_UNIX: 1628231200Smm case OS_MAC_OS: 1629231200Smm case OS_BEOS: 1630231200Smm rar->mode = archive_le32dec(file_header.file_attr); 1631231200Smm break; 1632231200Smm 1633231200Smm default: 1634231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1635231200Smm "Unknown file attributes from RAR file's host OS"); 1636231200Smm return (ARCHIVE_FATAL); 1637231200Smm } 1638231200Smm 1639231200Smm rar->bytes_uncopied = rar->bytes_unconsumed = 0; 1640238856Smm rar->lzss.position = rar->offset = 0; 1641248616Smm rar->offset_seek = 0; 1642238856Smm rar->dictionary_size = 0; 1643231200Smm rar->offset_outgoing = 0; 1644231200Smm rar->br.cache_avail = 0; 1645231200Smm rar->br.avail_in = 0; 1646231200Smm rar->crc_calculated = 0; 1647231200Smm rar->entry_eof = 0; 1648231200Smm rar->valid = 1; 1649231200Smm rar->is_ppmd_block = 0; 1650231200Smm rar->start_new_table = 1; 1651231200Smm free(rar->unp_buffer); 1652231200Smm rar->unp_buffer = NULL; 1653231200Smm rar->unp_offset = 0; 1654231200Smm rar->unp_buffer_size = UNP_BUFFER_SIZE; 1655231200Smm memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); 1656328827Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); 1657231200Smm rar->ppmd_valid = rar->ppmd_eod = 0; 1658231200Smm 1659231200Smm /* Don't set any archive entries for non-file header types */ 1660231200Smm if (head_type == NEWSUB_HEAD) 1661231200Smm return ret; 1662231200Smm 1663231200Smm archive_entry_set_mtime(entry, rar->mtime, rar->mnsec); 1664231200Smm archive_entry_set_ctime(entry, rar->ctime, rar->cnsec); 1665231200Smm archive_entry_set_atime(entry, rar->atime, rar->ansec); 1666231200Smm archive_entry_set_size(entry, rar->unp_size); 1667231200Smm archive_entry_set_mode(entry, rar->mode); 1668231200Smm 1669231200Smm if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv)) 1670231200Smm { 1671231200Smm if (errno == ENOMEM) 1672231200Smm { 1673231200Smm archive_set_error(&a->archive, ENOMEM, 1674231200Smm "Can't allocate memory for Pathname"); 1675231200Smm return (ARCHIVE_FATAL); 1676231200Smm } 1677231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1678231200Smm "Pathname cannot be converted from %s to current locale.", 1679231200Smm archive_string_conversion_charset_name(fn_sconv)); 1680231200Smm ret = (ARCHIVE_WARN); 1681231200Smm } 1682231200Smm 1683231200Smm if (((rar->mode) & AE_IFMT) == AE_IFLNK) 1684231200Smm { 1685231200Smm /* Make sure a symbolic-link file does not have its body. */ 1686231200Smm rar->bytes_remaining = 0; 1687231200Smm archive_entry_set_size(entry, 0); 1688231200Smm 1689231200Smm /* Read a symbolic-link name. */ 1690231200Smm if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN)) 1691231200Smm return ret2; 1692231200Smm if (ret > ret2) 1693231200Smm ret = ret2; 1694231200Smm } 1695231200Smm 1696231200Smm if (rar->bytes_remaining == 0) 1697231200Smm rar->entry_eof = 1; 1698231200Smm 1699231200Smm return ret; 1700231200Smm} 1701231200Smm 1702231200Smmstatic time_t 1703232153Smmget_time(int ttime) 1704231200Smm{ 1705231200Smm struct tm tm; 1706232153Smm tm.tm_sec = 2 * (ttime & 0x1f); 1707232153Smm tm.tm_min = (ttime >> 5) & 0x3f; 1708232153Smm tm.tm_hour = (ttime >> 11) & 0x1f; 1709232153Smm tm.tm_mday = (ttime >> 16) & 0x1f; 1710232153Smm tm.tm_mon = ((ttime >> 21) & 0x0f) - 1; 1711232153Smm tm.tm_year = ((ttime >> 25) & 0x7f) + 80; 1712231200Smm tm.tm_isdst = -1; 1713231200Smm return mktime(&tm); 1714231200Smm} 1715231200Smm 1716231200Smmstatic int 1717231200Smmread_exttime(const char *p, struct rar *rar, const char *endp) 1718231200Smm{ 1719231200Smm unsigned rmode, flags, rem, j, count; 1720232153Smm int ttime, i; 1721231200Smm struct tm *tm; 1722231200Smm time_t t; 1723231200Smm long nsec; 1724231200Smm 1725231200Smm if (p + 2 > endp) 1726231200Smm return (-1); 1727231200Smm flags = archive_le16dec(p); 1728231200Smm p += 2; 1729231200Smm 1730231200Smm for (i = 3; i >= 0; i--) 1731231200Smm { 1732231200Smm t = 0; 1733231200Smm if (i == 3) 1734231200Smm t = rar->mtime; 1735231200Smm rmode = flags >> i * 4; 1736231200Smm if (rmode & 8) 1737231200Smm { 1738231200Smm if (!t) 1739231200Smm { 1740231200Smm if (p + 4 > endp) 1741231200Smm return (-1); 1742232153Smm ttime = archive_le32dec(p); 1743232153Smm t = get_time(ttime); 1744231200Smm p += 4; 1745231200Smm } 1746231200Smm rem = 0; 1747231200Smm count = rmode & 3; 1748231200Smm if (p + count > endp) 1749231200Smm return (-1); 1750231200Smm for (j = 0; j < count; j++) 1751231200Smm { 1752318482Smm rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8); 1753231200Smm p++; 1754231200Smm } 1755231200Smm tm = localtime(&t); 1756231200Smm nsec = tm->tm_sec + rem / NS_UNIT; 1757231200Smm if (rmode & 4) 1758231200Smm { 1759231200Smm tm->tm_sec++; 1760231200Smm t = mktime(tm); 1761231200Smm } 1762231200Smm if (i == 3) 1763231200Smm { 1764231200Smm rar->mtime = t; 1765231200Smm rar->mnsec = nsec; 1766231200Smm } 1767231200Smm else if (i == 2) 1768231200Smm { 1769231200Smm rar->ctime = t; 1770231200Smm rar->cnsec = nsec; 1771231200Smm } 1772231200Smm else if (i == 1) 1773231200Smm { 1774231200Smm rar->atime = t; 1775231200Smm rar->ansec = nsec; 1776231200Smm } 1777231200Smm else 1778231200Smm { 1779231200Smm rar->arctime = t; 1780231200Smm rar->arcnsec = nsec; 1781231200Smm } 1782231200Smm } 1783231200Smm } 1784231200Smm return (0); 1785231200Smm} 1786231200Smm 1787231200Smmstatic int 1788231200Smmread_symlink_stored(struct archive_read *a, struct archive_entry *entry, 1789231200Smm struct archive_string_conv *sconv) 1790231200Smm{ 1791231200Smm const void *h; 1792231200Smm const char *p; 1793231200Smm struct rar *rar; 1794231200Smm int ret = (ARCHIVE_OK); 1795231200Smm 1796231200Smm rar = (struct rar *)(a->format->data); 1797248616Smm if ((h = rar_read_ahead(a, (size_t)rar->packed_size, NULL)) == NULL) 1798231200Smm return (ARCHIVE_FATAL); 1799231200Smm p = h; 1800231200Smm 1801238856Smm if (archive_entry_copy_symlink_l(entry, 1802238856Smm p, (size_t)rar->packed_size, sconv)) 1803231200Smm { 1804231200Smm if (errno == ENOMEM) 1805231200Smm { 1806231200Smm archive_set_error(&a->archive, ENOMEM, 1807231200Smm "Can't allocate memory for link"); 1808231200Smm return (ARCHIVE_FATAL); 1809231200Smm } 1810231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1811231200Smm "link cannot be converted from %s to current locale.", 1812231200Smm archive_string_conversion_charset_name(sconv)); 1813231200Smm ret = (ARCHIVE_WARN); 1814231200Smm } 1815231200Smm __archive_read_consume(a, rar->packed_size); 1816231200Smm return ret; 1817231200Smm} 1818231200Smm 1819231200Smmstatic int 1820231200Smmread_data_stored(struct archive_read *a, const void **buff, size_t *size, 1821231200Smm int64_t *offset) 1822231200Smm{ 1823231200Smm struct rar *rar; 1824231200Smm ssize_t bytes_avail; 1825231200Smm 1826231200Smm rar = (struct rar *)(a->format->data); 1827248616Smm if (rar->bytes_remaining == 0 && 1828248616Smm !(rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER)) 1829231200Smm { 1830231200Smm *buff = NULL; 1831231200Smm *size = 0; 1832231200Smm *offset = rar->offset; 1833231200Smm if (rar->file_crc != rar->crc_calculated) { 1834231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1835231200Smm "File CRC error"); 1836231200Smm return (ARCHIVE_FATAL); 1837231200Smm } 1838231200Smm rar->entry_eof = 1; 1839231200Smm return (ARCHIVE_EOF); 1840231200Smm } 1841231200Smm 1842248616Smm *buff = rar_read_ahead(a, 1, &bytes_avail); 1843231200Smm if (bytes_avail <= 0) 1844231200Smm { 1845231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1846231200Smm "Truncated RAR file data"); 1847231200Smm return (ARCHIVE_FATAL); 1848231200Smm } 1849231200Smm 1850231200Smm *size = bytes_avail; 1851231200Smm *offset = rar->offset; 1852231200Smm rar->offset += bytes_avail; 1853248616Smm rar->offset_seek += bytes_avail; 1854231200Smm rar->bytes_remaining -= bytes_avail; 1855231200Smm rar->bytes_unconsumed = bytes_avail; 1856231200Smm /* Calculate File CRC. */ 1857248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, 1858248616Smm (unsigned)bytes_avail); 1859231200Smm return (ARCHIVE_OK); 1860231200Smm} 1861231200Smm 1862231200Smmstatic int 1863231200Smmread_data_compressed(struct archive_read *a, const void **buff, size_t *size, 1864231200Smm int64_t *offset) 1865231200Smm{ 1866231200Smm struct rar *rar; 1867231200Smm int64_t start, end, actualend; 1868231200Smm size_t bs; 1869231200Smm int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i; 1870231200Smm 1871231200Smm rar = (struct rar *)(a->format->data); 1872231200Smm 1873231200Smm do { 1874231200Smm if (!rar->valid) 1875231200Smm return (ARCHIVE_FATAL); 1876231200Smm if (rar->ppmd_eod || 1877231200Smm (rar->dictionary_size && rar->offset >= rar->unp_size)) 1878231200Smm { 1879231200Smm if (rar->unp_offset > 0) { 1880231200Smm /* 1881231200Smm * We have unprocessed extracted data. write it out. 1882231200Smm */ 1883231200Smm *buff = rar->unp_buffer; 1884231200Smm *size = rar->unp_offset; 1885231200Smm *offset = rar->offset_outgoing; 1886231200Smm rar->offset_outgoing += *size; 1887231200Smm /* Calculate File CRC. */ 1888248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, 1889248616Smm (unsigned)*size); 1890231200Smm rar->unp_offset = 0; 1891231200Smm return (ARCHIVE_OK); 1892231200Smm } 1893231200Smm *buff = NULL; 1894231200Smm *size = 0; 1895231200Smm *offset = rar->offset; 1896231200Smm if (rar->file_crc != rar->crc_calculated) { 1897231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1898231200Smm "File CRC error"); 1899231200Smm return (ARCHIVE_FATAL); 1900231200Smm } 1901231200Smm rar->entry_eof = 1; 1902231200Smm return (ARCHIVE_EOF); 1903231200Smm } 1904231200Smm 1905231200Smm if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0) 1906231200Smm { 1907231200Smm if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) 1908231200Smm bs = rar->unp_buffer_size - rar->unp_offset; 1909231200Smm else 1910238856Smm bs = (size_t)rar->bytes_uncopied; 1911248616Smm ret = copy_from_lzss_window(a, buff, rar->offset, (int)bs); 1912231200Smm if (ret != ARCHIVE_OK) 1913231200Smm return (ret); 1914231200Smm rar->offset += bs; 1915231200Smm rar->bytes_uncopied -= bs; 1916231200Smm if (*buff != NULL) { 1917231200Smm rar->unp_offset = 0; 1918231200Smm *size = rar->unp_buffer_size; 1919231200Smm *offset = rar->offset_outgoing; 1920231200Smm rar->offset_outgoing += *size; 1921231200Smm /* Calculate File CRC. */ 1922248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, 1923248616Smm (unsigned)*size); 1924231200Smm return (ret); 1925231200Smm } 1926231200Smm continue; 1927231200Smm } 1928231200Smm 1929231200Smm if (!rar->br.next_in && 1930231200Smm (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN) 1931231200Smm return (ret); 1932231200Smm if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN))) 1933231200Smm return (ret); 1934231200Smm 1935231200Smm if (rar->is_ppmd_block) 1936231200Smm { 1937231200Smm if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1938231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1939231200Smm { 1940231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1941231200Smm "Invalid symbol"); 1942231200Smm return (ARCHIVE_FATAL); 1943231200Smm } 1944231200Smm if(sym != rar->ppmd_escape) 1945231200Smm { 1946231200Smm lzss_emit_literal(rar, sym); 1947231200Smm rar->bytes_uncopied++; 1948231200Smm } 1949231200Smm else 1950231200Smm { 1951231200Smm if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1952231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1953231200Smm { 1954231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1955231200Smm "Invalid symbol"); 1956231200Smm return (ARCHIVE_FATAL); 1957231200Smm } 1958231200Smm 1959231200Smm switch(code) 1960231200Smm { 1961231200Smm case 0: 1962231200Smm rar->start_new_table = 1; 1963231200Smm return read_data_compressed(a, buff, size, offset); 1964231200Smm 1965231200Smm case 2: 1966231200Smm rar->ppmd_eod = 1;/* End Of ppmd Data. */ 1967231200Smm continue; 1968231200Smm 1969231200Smm case 3: 1970231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1971231200Smm "Parsing filters is unsupported."); 1972231200Smm return (ARCHIVE_FAILED); 1973231200Smm 1974231200Smm case 4: 1975231200Smm lzss_offset = 0; 1976231200Smm for (i = 2; i >= 0; i--) 1977231200Smm { 1978231200Smm if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1979231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1980231200Smm { 1981231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1982231200Smm "Invalid symbol"); 1983231200Smm return (ARCHIVE_FATAL); 1984231200Smm } 1985231200Smm lzss_offset |= code << (i * 8); 1986231200Smm } 1987231200Smm if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1988231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1989231200Smm { 1990231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1991231200Smm "Invalid symbol"); 1992231200Smm return (ARCHIVE_FATAL); 1993231200Smm } 1994231200Smm lzss_emit_match(rar, lzss_offset + 2, length + 32); 1995231200Smm rar->bytes_uncopied += length + 32; 1996231200Smm break; 1997231200Smm 1998231200Smm case 5: 1999231200Smm if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 2000231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 2001231200Smm { 2002231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2003231200Smm "Invalid symbol"); 2004231200Smm return (ARCHIVE_FATAL); 2005231200Smm } 2006231200Smm lzss_emit_match(rar, 1, length + 4); 2007231200Smm rar->bytes_uncopied += length + 4; 2008231200Smm break; 2009231200Smm 2010231200Smm default: 2011231200Smm lzss_emit_literal(rar, sym); 2012231200Smm rar->bytes_uncopied++; 2013231200Smm } 2014231200Smm } 2015231200Smm } 2016231200Smm else 2017231200Smm { 2018231200Smm start = rar->offset; 2019231200Smm end = start + rar->dictionary_size; 2020231200Smm rar->filterstart = INT64_MAX; 2021231200Smm 2022231200Smm if ((actualend = expand(a, end)) < 0) 2023231200Smm return ((int)actualend); 2024231200Smm 2025231200Smm rar->bytes_uncopied = actualend - start; 2026231200Smm if (rar->bytes_uncopied == 0) { 2027231200Smm /* Broken RAR files cause this case. 2028231200Smm * NOTE: If this case were possible on a normal RAR file 2029231200Smm * we would find out where it was actually bad and 2030231200Smm * what we would do to solve it. */ 2031231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2032231200Smm "Internal error extracting RAR file"); 2033231200Smm return (ARCHIVE_FATAL); 2034231200Smm } 2035231200Smm } 2036231200Smm if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) 2037231200Smm bs = rar->unp_buffer_size - rar->unp_offset; 2038231200Smm else 2039238856Smm bs = (size_t)rar->bytes_uncopied; 2040248616Smm ret = copy_from_lzss_window(a, buff, rar->offset, (int)bs); 2041231200Smm if (ret != ARCHIVE_OK) 2042231200Smm return (ret); 2043231200Smm rar->offset += bs; 2044231200Smm rar->bytes_uncopied -= bs; 2045231200Smm /* 2046231200Smm * If *buff is NULL, it means unp_buffer is not full. 2047231200Smm * So we have to continue extracting a RAR file. 2048231200Smm */ 2049231200Smm } while (*buff == NULL); 2050231200Smm 2051231200Smm rar->unp_offset = 0; 2052231200Smm *size = rar->unp_buffer_size; 2053231200Smm *offset = rar->offset_outgoing; 2054231200Smm rar->offset_outgoing += *size; 2055231200Smm /* Calculate File CRC. */ 2056248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, (unsigned)*size); 2057231200Smm return ret; 2058231200Smm} 2059231200Smm 2060231200Smmstatic int 2061231200Smmparse_codes(struct archive_read *a) 2062231200Smm{ 2063231200Smm int i, j, val, n, r; 2064231200Smm unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags; 2065231200Smm unsigned int maxorder; 2066231200Smm struct huffman_code precode; 2067231200Smm struct rar *rar = (struct rar *)(a->format->data); 2068231200Smm struct rar_br *br = &(rar->br); 2069231200Smm 2070231200Smm free_codes(a); 2071231200Smm 2072231200Smm /* Skip to the next byte */ 2073231200Smm rar_br_consume_unalined_bits(br); 2074231200Smm 2075231200Smm /* PPMd block flag */ 2076231200Smm if (!rar_br_read_ahead(a, br, 1)) 2077231200Smm goto truncated_data; 2078231200Smm if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0) 2079231200Smm { 2080231200Smm rar_br_consume(br, 1); 2081231200Smm if (!rar_br_read_ahead(a, br, 7)) 2082231200Smm goto truncated_data; 2083231200Smm ppmd_flags = rar_br_bits(br, 7); 2084231200Smm rar_br_consume(br, 7); 2085231200Smm 2086231200Smm /* Memory is allocated in MB */ 2087231200Smm if (ppmd_flags & 0x20) 2088231200Smm { 2089231200Smm if (!rar_br_read_ahead(a, br, 8)) 2090231200Smm goto truncated_data; 2091231200Smm rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20; 2092231200Smm rar_br_consume(br, 8); 2093231200Smm } 2094231200Smm 2095231200Smm if (ppmd_flags & 0x40) 2096231200Smm { 2097231200Smm if (!rar_br_read_ahead(a, br, 8)) 2098231200Smm goto truncated_data; 2099231200Smm rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8); 2100231200Smm rar_br_consume(br, 8); 2101231200Smm } 2102231200Smm else 2103231200Smm rar->ppmd_escape = 2; 2104231200Smm 2105231200Smm if (ppmd_flags & 0x20) 2106231200Smm { 2107231200Smm maxorder = (ppmd_flags & 0x1F) + 1; 2108231200Smm if(maxorder > 16) 2109231200Smm maxorder = 16 + (maxorder - 16) * 3; 2110231200Smm 2111231200Smm if (maxorder == 1) 2112231200Smm { 2113231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2114231200Smm "Truncated RAR file data"); 2115231200Smm return (ARCHIVE_FATAL); 2116231200Smm } 2117231200Smm 2118231200Smm /* Make sure ppmd7_contest is freed before Ppmd7_Construct 2119231200Smm * because reading a broken file cause this abnormal sequence. */ 2120328827Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); 2121231200Smm 2122231200Smm rar->bytein.a = a; 2123231200Smm rar->bytein.Read = &ppmd_read; 2124231200Smm __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec); 2125231200Smm rar->range_dec.Stream = &rar->bytein; 2126231200Smm __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context); 2127231200Smm 2128302075Smm if (rar->dictionary_size == 0) { 2129302075Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2130302075Smm "Invalid zero dictionary size"); 2131302075Smm return (ARCHIVE_FATAL); 2132302075Smm } 2133302075Smm 2134231200Smm if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context, 2135328827Smm rar->dictionary_size)) 2136231200Smm { 2137231200Smm archive_set_error(&a->archive, ENOMEM, 2138231200Smm "Out of memory"); 2139231200Smm return (ARCHIVE_FATAL); 2140231200Smm } 2141231200Smm if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) 2142231200Smm { 2143231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2144231200Smm "Unable to initialize PPMd range decoder"); 2145231200Smm return (ARCHIVE_FATAL); 2146231200Smm } 2147231200Smm __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder); 2148231200Smm rar->ppmd_valid = 1; 2149231200Smm } 2150231200Smm else 2151231200Smm { 2152231200Smm if (!rar->ppmd_valid) { 2153231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2154231200Smm "Invalid PPMd sequence"); 2155231200Smm return (ARCHIVE_FATAL); 2156231200Smm } 2157231200Smm if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) 2158231200Smm { 2159231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2160231200Smm "Unable to initialize PPMd range decoder"); 2161231200Smm return (ARCHIVE_FATAL); 2162231200Smm } 2163231200Smm } 2164231200Smm } 2165231200Smm else 2166231200Smm { 2167231200Smm rar_br_consume(br, 1); 2168231200Smm 2169231200Smm /* Keep existing table flag */ 2170231200Smm if (!rar_br_read_ahead(a, br, 1)) 2171231200Smm goto truncated_data; 2172231200Smm if (!rar_br_bits(br, 1)) 2173231200Smm memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); 2174231200Smm rar_br_consume(br, 1); 2175231200Smm 2176231200Smm memset(&bitlengths, 0, sizeof(bitlengths)); 2177231200Smm for (i = 0; i < MAX_SYMBOLS;) 2178231200Smm { 2179231200Smm if (!rar_br_read_ahead(a, br, 4)) 2180231200Smm goto truncated_data; 2181231200Smm bitlengths[i++] = rar_br_bits(br, 4); 2182231200Smm rar_br_consume(br, 4); 2183231200Smm if (bitlengths[i-1] == 0xF) 2184231200Smm { 2185231200Smm if (!rar_br_read_ahead(a, br, 4)) 2186231200Smm goto truncated_data; 2187231200Smm zerocount = rar_br_bits(br, 4); 2188231200Smm rar_br_consume(br, 4); 2189231200Smm if (zerocount) 2190231200Smm { 2191231200Smm i--; 2192231200Smm for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++) 2193231200Smm bitlengths[i++] = 0; 2194231200Smm } 2195231200Smm } 2196231200Smm } 2197231200Smm 2198231200Smm memset(&precode, 0, sizeof(precode)); 2199231200Smm r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH); 2200231200Smm if (r != ARCHIVE_OK) { 2201231200Smm free(precode.tree); 2202231200Smm free(precode.table); 2203231200Smm return (r); 2204231200Smm } 2205231200Smm 2206231200Smm for (i = 0; i < HUFFMAN_TABLE_SIZE;) 2207231200Smm { 2208231200Smm if ((val = read_next_symbol(a, &precode)) < 0) { 2209231200Smm free(precode.tree); 2210231200Smm free(precode.table); 2211231200Smm return (ARCHIVE_FATAL); 2212231200Smm } 2213231200Smm if (val < 16) 2214231200Smm { 2215231200Smm rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF; 2216231200Smm i++; 2217231200Smm } 2218231200Smm else if (val < 18) 2219231200Smm { 2220231200Smm if (i == 0) 2221231200Smm { 2222231200Smm free(precode.tree); 2223231200Smm free(precode.table); 2224231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2225231200Smm "Internal error extracting RAR file."); 2226231200Smm return (ARCHIVE_FATAL); 2227231200Smm } 2228231200Smm 2229231200Smm if(val == 16) { 2230231200Smm if (!rar_br_read_ahead(a, br, 3)) { 2231231200Smm free(precode.tree); 2232231200Smm free(precode.table); 2233231200Smm goto truncated_data; 2234231200Smm } 2235231200Smm n = rar_br_bits(br, 3) + 3; 2236231200Smm rar_br_consume(br, 3); 2237231200Smm } else { 2238231200Smm if (!rar_br_read_ahead(a, br, 7)) { 2239231200Smm free(precode.tree); 2240231200Smm free(precode.table); 2241231200Smm goto truncated_data; 2242231200Smm } 2243231200Smm n = rar_br_bits(br, 7) + 11; 2244231200Smm rar_br_consume(br, 7); 2245231200Smm } 2246231200Smm 2247231200Smm for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) 2248231200Smm { 2249231200Smm rar->lengthtable[i] = rar->lengthtable[i-1]; 2250231200Smm i++; 2251231200Smm } 2252231200Smm } 2253231200Smm else 2254231200Smm { 2255231200Smm if(val == 18) { 2256231200Smm if (!rar_br_read_ahead(a, br, 3)) { 2257231200Smm free(precode.tree); 2258231200Smm free(precode.table); 2259231200Smm goto truncated_data; 2260231200Smm } 2261231200Smm n = rar_br_bits(br, 3) + 3; 2262231200Smm rar_br_consume(br, 3); 2263231200Smm } else { 2264231200Smm if (!rar_br_read_ahead(a, br, 7)) { 2265231200Smm free(precode.tree); 2266231200Smm free(precode.table); 2267231200Smm goto truncated_data; 2268231200Smm } 2269231200Smm n = rar_br_bits(br, 7) + 11; 2270231200Smm rar_br_consume(br, 7); 2271231200Smm } 2272231200Smm 2273231200Smm for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) 2274231200Smm rar->lengthtable[i++] = 0; 2275231200Smm } 2276231200Smm } 2277231200Smm free(precode.tree); 2278231200Smm free(precode.table); 2279231200Smm 2280231200Smm r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE, 2281231200Smm MAX_SYMBOL_LENGTH); 2282231200Smm if (r != ARCHIVE_OK) 2283231200Smm return (r); 2284231200Smm r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE], 2285231200Smm OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); 2286231200Smm if (r != ARCHIVE_OK) 2287231200Smm return (r); 2288231200Smm r = create_code(a, &rar->lowoffsetcode, 2289231200Smm &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE], 2290231200Smm LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); 2291231200Smm if (r != ARCHIVE_OK) 2292231200Smm return (r); 2293231200Smm r = create_code(a, &rar->lengthcode, 2294231200Smm &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE + 2295231200Smm LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH); 2296231200Smm if (r != ARCHIVE_OK) 2297231200Smm return (r); 2298231200Smm } 2299231200Smm 2300231200Smm if (!rar->dictionary_size || !rar->lzss.window) 2301231200Smm { 2302231200Smm /* Seems as though dictionary sizes are not used. Even so, minimize 2303231200Smm * memory usage as much as possible. 2304231200Smm */ 2305248616Smm void *new_window; 2306248616Smm unsigned int new_size; 2307248616Smm 2308231200Smm if (rar->unp_size >= DICTIONARY_MAX_SIZE) 2309248616Smm new_size = DICTIONARY_MAX_SIZE; 2310231200Smm else 2311248616Smm new_size = rar_fls((unsigned int)rar->unp_size) << 1; 2312342360Smm if (new_size == 0) { 2313342360Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2314342360Smm "Zero window size is invalid."); 2315342360Smm return (ARCHIVE_FATAL); 2316342360Smm } 2317248616Smm new_window = realloc(rar->lzss.window, new_size); 2318248616Smm if (new_window == NULL) { 2319231200Smm archive_set_error(&a->archive, ENOMEM, 2320231200Smm "Unable to allocate memory for uncompressed data."); 2321231200Smm return (ARCHIVE_FATAL); 2322231200Smm } 2323248616Smm rar->lzss.window = (unsigned char *)new_window; 2324248616Smm rar->dictionary_size = new_size; 2325231200Smm memset(rar->lzss.window, 0, rar->dictionary_size); 2326231200Smm rar->lzss.mask = rar->dictionary_size - 1; 2327231200Smm } 2328231200Smm 2329231200Smm rar->start_new_table = 0; 2330231200Smm return (ARCHIVE_OK); 2331231200Smmtruncated_data: 2332231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2333231200Smm "Truncated RAR file data"); 2334231200Smm rar->valid = 0; 2335231200Smm return (ARCHIVE_FATAL); 2336231200Smm} 2337231200Smm 2338231200Smmstatic void 2339231200Smmfree_codes(struct archive_read *a) 2340231200Smm{ 2341231200Smm struct rar *rar = (struct rar *)(a->format->data); 2342231200Smm free(rar->maincode.tree); 2343231200Smm free(rar->offsetcode.tree); 2344231200Smm free(rar->lowoffsetcode.tree); 2345231200Smm free(rar->lengthcode.tree); 2346231200Smm free(rar->maincode.table); 2347231200Smm free(rar->offsetcode.table); 2348231200Smm free(rar->lowoffsetcode.table); 2349231200Smm free(rar->lengthcode.table); 2350231200Smm memset(&rar->maincode, 0, sizeof(rar->maincode)); 2351231200Smm memset(&rar->offsetcode, 0, sizeof(rar->offsetcode)); 2352231200Smm memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode)); 2353231200Smm memset(&rar->lengthcode, 0, sizeof(rar->lengthcode)); 2354231200Smm} 2355231200Smm 2356231200Smm 2357231200Smmstatic int 2358231200Smmread_next_symbol(struct archive_read *a, struct huffman_code *code) 2359231200Smm{ 2360231200Smm unsigned char bit; 2361231200Smm unsigned int bits; 2362231200Smm int length, value, node; 2363231200Smm struct rar *rar; 2364231200Smm struct rar_br *br; 2365231200Smm 2366231200Smm if (!code->table) 2367231200Smm { 2368231200Smm if (make_table(a, code) != (ARCHIVE_OK)) 2369231200Smm return -1; 2370231200Smm } 2371231200Smm 2372231200Smm rar = (struct rar *)(a->format->data); 2373231200Smm br = &(rar->br); 2374231200Smm 2375231200Smm /* Look ahead (peek) at bits */ 2376231200Smm if (!rar_br_read_ahead(a, br, code->tablesize)) { 2377231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2378231200Smm "Truncated RAR file data"); 2379231200Smm rar->valid = 0; 2380231200Smm return -1; 2381231200Smm } 2382231200Smm bits = rar_br_bits(br, code->tablesize); 2383231200Smm 2384231200Smm length = code->table[bits].length; 2385231200Smm value = code->table[bits].value; 2386231200Smm 2387231200Smm if (length < 0) 2388231200Smm { 2389231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2390231200Smm "Invalid prefix code in bitstream"); 2391231200Smm return -1; 2392231200Smm } 2393231200Smm 2394231200Smm if (length <= code->tablesize) 2395231200Smm { 2396231200Smm /* Skip length bits */ 2397231200Smm rar_br_consume(br, length); 2398231200Smm return value; 2399231200Smm } 2400231200Smm 2401231200Smm /* Skip tablesize bits */ 2402231200Smm rar_br_consume(br, code->tablesize); 2403231200Smm 2404231200Smm node = value; 2405231200Smm while (!(code->tree[node].branches[0] == 2406231200Smm code->tree[node].branches[1])) 2407231200Smm { 2408231200Smm if (!rar_br_read_ahead(a, br, 1)) { 2409231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2410231200Smm "Truncated RAR file data"); 2411231200Smm rar->valid = 0; 2412231200Smm return -1; 2413231200Smm } 2414231200Smm bit = rar_br_bits(br, 1); 2415231200Smm rar_br_consume(br, 1); 2416231200Smm 2417231200Smm if (code->tree[node].branches[bit] < 0) 2418231200Smm { 2419231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2420231200Smm "Invalid prefix code in bitstream"); 2421231200Smm return -1; 2422231200Smm } 2423231200Smm node = code->tree[node].branches[bit]; 2424231200Smm } 2425231200Smm 2426231200Smm return code->tree[node].branches[0]; 2427231200Smm} 2428231200Smm 2429231200Smmstatic int 2430231200Smmcreate_code(struct archive_read *a, struct huffman_code *code, 2431231200Smm unsigned char *lengths, int numsymbols, char maxlength) 2432231200Smm{ 2433231200Smm int i, j, codebits = 0, symbolsleft = numsymbols; 2434231200Smm 2435299529Smm code->numentries = 0; 2436299529Smm code->numallocatedentries = 0; 2437231200Smm if (new_node(code) < 0) { 2438231200Smm archive_set_error(&a->archive, ENOMEM, 2439231200Smm "Unable to allocate memory for node data."); 2440231200Smm return (ARCHIVE_FATAL); 2441231200Smm } 2442231200Smm code->numentries = 1; 2443231200Smm code->minlength = INT_MAX; 2444231200Smm code->maxlength = INT_MIN; 2445231200Smm codebits = 0; 2446231200Smm for(i = 1; i <= maxlength; i++) 2447231200Smm { 2448231200Smm for(j = 0; j < numsymbols; j++) 2449231200Smm { 2450231200Smm if (lengths[j] != i) continue; 2451231200Smm if (add_value(a, code, j, codebits, i) != ARCHIVE_OK) 2452231200Smm return (ARCHIVE_FATAL); 2453231200Smm codebits++; 2454231200Smm if (--symbolsleft <= 0) { break; break; } 2455231200Smm } 2456231200Smm codebits <<= 1; 2457231200Smm } 2458231200Smm return (ARCHIVE_OK); 2459231200Smm} 2460231200Smm 2461231200Smmstatic int 2462231200Smmadd_value(struct archive_read *a, struct huffman_code *code, int value, 2463231200Smm int codebits, int length) 2464231200Smm{ 2465231200Smm int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode; 2466231200Smm 2467231200Smm free(code->table); 2468231200Smm code->table = NULL; 2469231200Smm 2470231200Smm if(length > code->maxlength) 2471231200Smm code->maxlength = length; 2472231200Smm if(length < code->minlength) 2473231200Smm code->minlength = length; 2474231200Smm 2475231200Smm repeatpos = -1; 2476231200Smm if (repeatpos == 0 || (repeatpos >= 0 2477231200Smm && (((codebits >> (repeatpos - 1)) & 3) == 0 2478231200Smm || ((codebits >> (repeatpos - 1)) & 3) == 3))) 2479231200Smm { 2480231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2481231200Smm "Invalid repeat position"); 2482231200Smm return (ARCHIVE_FATAL); 2483231200Smm } 2484231200Smm 2485231200Smm lastnode = 0; 2486231200Smm for (bitpos = length - 1; bitpos >= 0; bitpos--) 2487231200Smm { 2488231200Smm bit = (codebits >> bitpos) & 1; 2489231200Smm 2490231200Smm /* Leaf node check */ 2491231200Smm if (code->tree[lastnode].branches[0] == 2492231200Smm code->tree[lastnode].branches[1]) 2493231200Smm { 2494231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2495231200Smm "Prefix found"); 2496231200Smm return (ARCHIVE_FATAL); 2497231200Smm } 2498231200Smm 2499231200Smm if (bitpos == repeatpos) 2500231200Smm { 2501231200Smm /* Open branch check */ 2502231200Smm if (!(code->tree[lastnode].branches[bit] < 0)) 2503231200Smm { 2504231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2505231200Smm "Invalid repeating code"); 2506231200Smm return (ARCHIVE_FATAL); 2507231200Smm } 2508231200Smm 2509231200Smm if ((repeatnode = new_node(code)) < 0) { 2510231200Smm archive_set_error(&a->archive, ENOMEM, 2511231200Smm "Unable to allocate memory for node data."); 2512231200Smm return (ARCHIVE_FATAL); 2513231200Smm } 2514231200Smm if ((nextnode = new_node(code)) < 0) { 2515231200Smm archive_set_error(&a->archive, ENOMEM, 2516231200Smm "Unable to allocate memory for node data."); 2517231200Smm return (ARCHIVE_FATAL); 2518231200Smm } 2519231200Smm 2520231200Smm /* Set branches */ 2521231200Smm code->tree[lastnode].branches[bit] = repeatnode; 2522231200Smm code->tree[repeatnode].branches[bit] = repeatnode; 2523231200Smm code->tree[repeatnode].branches[bit^1] = nextnode; 2524231200Smm lastnode = nextnode; 2525231200Smm 2526231200Smm bitpos++; /* terminating bit already handled, skip it */ 2527231200Smm } 2528231200Smm else 2529231200Smm { 2530231200Smm /* Open branch check */ 2531231200Smm if (code->tree[lastnode].branches[bit] < 0) 2532231200Smm { 2533231200Smm if (new_node(code) < 0) { 2534231200Smm archive_set_error(&a->archive, ENOMEM, 2535231200Smm "Unable to allocate memory for node data."); 2536231200Smm return (ARCHIVE_FATAL); 2537231200Smm } 2538231200Smm code->tree[lastnode].branches[bit] = code->numentries++; 2539231200Smm } 2540231200Smm 2541231200Smm /* set to branch */ 2542231200Smm lastnode = code->tree[lastnode].branches[bit]; 2543231200Smm } 2544231200Smm } 2545231200Smm 2546231200Smm if (!(code->tree[lastnode].branches[0] == -1 2547231200Smm && code->tree[lastnode].branches[1] == -2)) 2548231200Smm { 2549231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2550231200Smm "Prefix found"); 2551231200Smm return (ARCHIVE_FATAL); 2552231200Smm } 2553231200Smm 2554231200Smm /* Set leaf value */ 2555231200Smm code->tree[lastnode].branches[0] = value; 2556231200Smm code->tree[lastnode].branches[1] = value; 2557231200Smm 2558231200Smm return (ARCHIVE_OK); 2559231200Smm} 2560231200Smm 2561231200Smmstatic int 2562231200Smmnew_node(struct huffman_code *code) 2563231200Smm{ 2564248616Smm void *new_tree; 2565299529Smm if (code->numallocatedentries == code->numentries) { 2566299529Smm int new_num_entries = 256; 2567299529Smm if (code->numentries > 0) { 2568299529Smm new_num_entries = code->numentries * 2; 2569299529Smm } 2570299529Smm new_tree = realloc(code->tree, new_num_entries * sizeof(*code->tree)); 2571299529Smm if (new_tree == NULL) 2572299529Smm return (-1); 2573299529Smm code->tree = (struct huffman_tree_node *)new_tree; 2574299529Smm code->numallocatedentries = new_num_entries; 2575299529Smm } 2576231200Smm code->tree[code->numentries].branches[0] = -1; 2577231200Smm code->tree[code->numentries].branches[1] = -2; 2578231200Smm return 1; 2579231200Smm} 2580231200Smm 2581231200Smmstatic int 2582231200Smmmake_table(struct archive_read *a, struct huffman_code *code) 2583231200Smm{ 2584231200Smm if (code->maxlength < code->minlength || code->maxlength > 10) 2585231200Smm code->tablesize = 10; 2586231200Smm else 2587231200Smm code->tablesize = code->maxlength; 2588231200Smm 2589231200Smm code->table = 2590248616Smm (struct huffman_table_entry *)calloc(1, sizeof(*code->table) 2591248616Smm * ((size_t)1 << code->tablesize)); 2592231200Smm 2593231200Smm return make_table_recurse(a, code, 0, code->table, 0, code->tablesize); 2594231200Smm} 2595231200Smm 2596231200Smmstatic int 2597231200Smmmake_table_recurse(struct archive_read *a, struct huffman_code *code, int node, 2598231200Smm struct huffman_table_entry *table, int depth, 2599231200Smm int maxdepth) 2600231200Smm{ 2601231200Smm int currtablesize, i, ret = (ARCHIVE_OK); 2602231200Smm 2603231200Smm if (!code->tree) 2604231200Smm { 2605231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2606231200Smm "Huffman tree was not created."); 2607231200Smm return (ARCHIVE_FATAL); 2608231200Smm } 2609231200Smm if (node < 0 || node >= code->numentries) 2610231200Smm { 2611231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2612231200Smm "Invalid location to Huffman tree specified."); 2613231200Smm return (ARCHIVE_FATAL); 2614231200Smm } 2615231200Smm 2616231200Smm currtablesize = 1 << (maxdepth - depth); 2617231200Smm 2618231200Smm if (code->tree[node].branches[0] == 2619231200Smm code->tree[node].branches[1]) 2620231200Smm { 2621231200Smm for(i = 0; i < currtablesize; i++) 2622231200Smm { 2623231200Smm table[i].length = depth; 2624231200Smm table[i].value = code->tree[node].branches[0]; 2625231200Smm } 2626231200Smm } 2627231200Smm else if (node < 0) 2628231200Smm { 2629231200Smm for(i = 0; i < currtablesize; i++) 2630231200Smm table[i].length = -1; 2631231200Smm } 2632231200Smm else 2633231200Smm { 2634231200Smm if(depth == maxdepth) 2635231200Smm { 2636231200Smm table[0].length = maxdepth + 1; 2637231200Smm table[0].value = node; 2638231200Smm } 2639231200Smm else 2640231200Smm { 2641231200Smm ret |= make_table_recurse(a, code, code->tree[node].branches[0], table, 2642231200Smm depth + 1, maxdepth); 2643231200Smm ret |= make_table_recurse(a, code, code->tree[node].branches[1], 2644231200Smm table + currtablesize / 2, depth + 1, maxdepth); 2645231200Smm } 2646231200Smm } 2647231200Smm return ret; 2648231200Smm} 2649231200Smm 2650231200Smmstatic int64_t 2651231200Smmexpand(struct archive_read *a, int64_t end) 2652231200Smm{ 2653231200Smm static const unsigned char lengthbases[] = 2654231200Smm { 0, 1, 2, 3, 4, 5, 6, 2655231200Smm 7, 8, 10, 12, 14, 16, 20, 2656231200Smm 24, 28, 32, 40, 48, 56, 64, 2657231200Smm 80, 96, 112, 128, 160, 192, 224 }; 2658231200Smm static const unsigned char lengthbits[] = 2659231200Smm { 0, 0, 0, 0, 0, 0, 0, 2660231200Smm 0, 1, 1, 1, 1, 2, 2, 2661231200Smm 2, 2, 3, 3, 3, 3, 4, 2662231200Smm 4, 4, 4, 5, 5, 5, 5 }; 2663231200Smm static const unsigned int offsetbases[] = 2664231200Smm { 0, 1, 2, 3, 4, 6, 2665231200Smm 8, 12, 16, 24, 32, 48, 2666231200Smm 64, 96, 128, 192, 256, 384, 2667231200Smm 512, 768, 1024, 1536, 2048, 3072, 2668231200Smm 4096, 6144, 8192, 12288, 16384, 24576, 2669231200Smm 32768, 49152, 65536, 98304, 131072, 196608, 2670231200Smm 262144, 327680, 393216, 458752, 524288, 589824, 2671231200Smm 655360, 720896, 786432, 851968, 917504, 983040, 2672231200Smm 1048576, 1310720, 1572864, 1835008, 2097152, 2359296, 2673231200Smm 2621440, 2883584, 3145728, 3407872, 3670016, 3932160 }; 2674231200Smm static const unsigned char offsetbits[] = 2675231200Smm { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 2676231200Smm 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 2677231200Smm 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 2678231200Smm 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2679231200Smm 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; 2680231200Smm static const unsigned char shortbases[] = 2681231200Smm { 0, 4, 8, 16, 32, 64, 128, 192 }; 2682231200Smm static const unsigned char shortbits[] = 2683231200Smm { 2, 2, 3, 4, 5, 6, 6, 6 }; 2684231200Smm 2685231200Smm int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol; 2686231200Smm unsigned char newfile; 2687231200Smm struct rar *rar = (struct rar *)(a->format->data); 2688231200Smm struct rar_br *br = &(rar->br); 2689231200Smm 2690231200Smm if (rar->filterstart < end) 2691231200Smm end = rar->filterstart; 2692231200Smm 2693231200Smm while (1) 2694231200Smm { 2695231200Smm if (rar->output_last_match && 2696231200Smm lzss_position(&rar->lzss) + rar->lastlength <= end) 2697231200Smm { 2698231200Smm lzss_emit_match(rar, rar->lastoffset, rar->lastlength); 2699231200Smm rar->output_last_match = 0; 2700231200Smm } 2701231200Smm 2702231200Smm if(rar->is_ppmd_block || rar->output_last_match || 2703231200Smm lzss_position(&rar->lzss) >= end) 2704231200Smm return lzss_position(&rar->lzss); 2705231200Smm 2706231200Smm if ((symbol = read_next_symbol(a, &rar->maincode)) < 0) 2707231200Smm return (ARCHIVE_FATAL); 2708231200Smm rar->output_last_match = 0; 2709299529Smm 2710231200Smm if (symbol < 256) 2711231200Smm { 2712231200Smm lzss_emit_literal(rar, symbol); 2713231200Smm continue; 2714231200Smm } 2715231200Smm else if (symbol == 256) 2716231200Smm { 2717231200Smm if (!rar_br_read_ahead(a, br, 1)) 2718231200Smm goto truncated_data; 2719231200Smm newfile = !rar_br_bits(br, 1); 2720231200Smm rar_br_consume(br, 1); 2721231200Smm 2722231200Smm if(newfile) 2723231200Smm { 2724231200Smm rar->start_new_block = 1; 2725231200Smm if (!rar_br_read_ahead(a, br, 1)) 2726231200Smm goto truncated_data; 2727231200Smm rar->start_new_table = rar_br_bits(br, 1); 2728231200Smm rar_br_consume(br, 1); 2729231200Smm return lzss_position(&rar->lzss); 2730231200Smm } 2731231200Smm else 2732231200Smm { 2733231200Smm if (parse_codes(a) != ARCHIVE_OK) 2734231200Smm return (ARCHIVE_FATAL); 2735231200Smm continue; 2736231200Smm } 2737231200Smm } 2738231200Smm else if(symbol==257) 2739231200Smm { 2740231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 2741231200Smm "Parsing filters is unsupported."); 2742231200Smm return (ARCHIVE_FAILED); 2743231200Smm } 2744231200Smm else if(symbol==258) 2745231200Smm { 2746231200Smm if(rar->lastlength == 0) 2747231200Smm continue; 2748231200Smm 2749231200Smm offs = rar->lastoffset; 2750231200Smm len = rar->lastlength; 2751231200Smm } 2752231200Smm else if (symbol <= 262) 2753231200Smm { 2754231200Smm offsindex = symbol - 259; 2755231200Smm offs = rar->oldoffset[offsindex]; 2756231200Smm 2757231200Smm if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0) 2758231200Smm goto bad_data; 2759232153Smm if (lensymbol > (int)(sizeof(lengthbases)/sizeof(lengthbases[0]))) 2760231200Smm goto bad_data; 2761232153Smm if (lensymbol > (int)(sizeof(lengthbits)/sizeof(lengthbits[0]))) 2762231200Smm goto bad_data; 2763231200Smm len = lengthbases[lensymbol] + 2; 2764231200Smm if (lengthbits[lensymbol] > 0) { 2765231200Smm if (!rar_br_read_ahead(a, br, lengthbits[lensymbol])) 2766231200Smm goto truncated_data; 2767231200Smm len += rar_br_bits(br, lengthbits[lensymbol]); 2768231200Smm rar_br_consume(br, lengthbits[lensymbol]); 2769231200Smm } 2770231200Smm 2771231200Smm for (i = offsindex; i > 0; i--) 2772231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2773231200Smm rar->oldoffset[0] = offs; 2774231200Smm } 2775231200Smm else if(symbol<=270) 2776231200Smm { 2777231200Smm offs = shortbases[symbol-263] + 1; 2778231200Smm if(shortbits[symbol-263] > 0) { 2779231200Smm if (!rar_br_read_ahead(a, br, shortbits[symbol-263])) 2780231200Smm goto truncated_data; 2781231200Smm offs += rar_br_bits(br, shortbits[symbol-263]); 2782231200Smm rar_br_consume(br, shortbits[symbol-263]); 2783231200Smm } 2784231200Smm 2785231200Smm len = 2; 2786231200Smm 2787231200Smm for(i = 3; i > 0; i--) 2788231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2789231200Smm rar->oldoffset[0] = offs; 2790231200Smm } 2791231200Smm else 2792231200Smm { 2793232153Smm if (symbol-271 > (int)(sizeof(lengthbases)/sizeof(lengthbases[0]))) 2794231200Smm goto bad_data; 2795232153Smm if (symbol-271 > (int)(sizeof(lengthbits)/sizeof(lengthbits[0]))) 2796231200Smm goto bad_data; 2797231200Smm len = lengthbases[symbol-271]+3; 2798231200Smm if(lengthbits[symbol-271] > 0) { 2799231200Smm if (!rar_br_read_ahead(a, br, lengthbits[symbol-271])) 2800231200Smm goto truncated_data; 2801231200Smm len += rar_br_bits(br, lengthbits[symbol-271]); 2802231200Smm rar_br_consume(br, lengthbits[symbol-271]); 2803231200Smm } 2804231200Smm 2805231200Smm if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0) 2806231200Smm goto bad_data; 2807232153Smm if (offssymbol > (int)(sizeof(offsetbases)/sizeof(offsetbases[0]))) 2808231200Smm goto bad_data; 2809232153Smm if (offssymbol > (int)(sizeof(offsetbits)/sizeof(offsetbits[0]))) 2810231200Smm goto bad_data; 2811231200Smm offs = offsetbases[offssymbol]+1; 2812231200Smm if(offsetbits[offssymbol] > 0) 2813231200Smm { 2814231200Smm if(offssymbol > 9) 2815231200Smm { 2816231200Smm if(offsetbits[offssymbol] > 4) { 2817231200Smm if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4)) 2818231200Smm goto truncated_data; 2819231200Smm offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4; 2820231200Smm rar_br_consume(br, offsetbits[offssymbol] - 4); 2821231200Smm } 2822231200Smm 2823231200Smm if(rar->numlowoffsetrepeats > 0) 2824231200Smm { 2825231200Smm rar->numlowoffsetrepeats--; 2826231200Smm offs += rar->lastlowoffset; 2827231200Smm } 2828231200Smm else 2829231200Smm { 2830231200Smm if ((lowoffsetsymbol = 2831231200Smm read_next_symbol(a, &rar->lowoffsetcode)) < 0) 2832231200Smm return (ARCHIVE_FATAL); 2833231200Smm if(lowoffsetsymbol == 16) 2834231200Smm { 2835231200Smm rar->numlowoffsetrepeats = 15; 2836231200Smm offs += rar->lastlowoffset; 2837231200Smm } 2838231200Smm else 2839231200Smm { 2840231200Smm offs += lowoffsetsymbol; 2841231200Smm rar->lastlowoffset = lowoffsetsymbol; 2842231200Smm } 2843231200Smm } 2844231200Smm } 2845231200Smm else { 2846231200Smm if (!rar_br_read_ahead(a, br, offsetbits[offssymbol])) 2847231200Smm goto truncated_data; 2848231200Smm offs += rar_br_bits(br, offsetbits[offssymbol]); 2849231200Smm rar_br_consume(br, offsetbits[offssymbol]); 2850231200Smm } 2851231200Smm } 2852231200Smm 2853231200Smm if (offs >= 0x40000) 2854231200Smm len++; 2855231200Smm if (offs >= 0x2000) 2856231200Smm len++; 2857231200Smm 2858231200Smm for(i = 3; i > 0; i--) 2859231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2860231200Smm rar->oldoffset[0] = offs; 2861231200Smm } 2862231200Smm 2863231200Smm rar->lastoffset = offs; 2864231200Smm rar->lastlength = len; 2865231200Smm rar->output_last_match = 1; 2866231200Smm } 2867231200Smmtruncated_data: 2868231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2869231200Smm "Truncated RAR file data"); 2870231200Smm rar->valid = 0; 2871231200Smm return (ARCHIVE_FATAL); 2872231200Smmbad_data: 2873231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2874231200Smm "Bad RAR file data"); 2875231200Smm return (ARCHIVE_FATAL); 2876231200Smm} 2877231200Smm 2878231200Smmstatic int 2879231200Smmcopy_from_lzss_window(struct archive_read *a, const void **buffer, 2880231200Smm int64_t startpos, int length) 2881231200Smm{ 2882231200Smm int windowoffs, firstpart; 2883231200Smm struct rar *rar = (struct rar *)(a->format->data); 2884231200Smm 2885231200Smm if (!rar->unp_buffer) 2886231200Smm { 2887231200Smm if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL) 2888231200Smm { 2889231200Smm archive_set_error(&a->archive, ENOMEM, 2890231200Smm "Unable to allocate memory for uncompressed data."); 2891231200Smm return (ARCHIVE_FATAL); 2892231200Smm } 2893231200Smm } 2894231200Smm 2895231200Smm windowoffs = lzss_offset_for_position(&rar->lzss, startpos); 2896302075Smm if(windowoffs + length <= lzss_size(&rar->lzss)) { 2897231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs], 2898231200Smm length); 2899302075Smm } else if (length <= lzss_size(&rar->lzss)) { 2900231200Smm firstpart = lzss_size(&rar->lzss) - windowoffs; 2901231200Smm if (firstpart < 0) { 2902231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2903231200Smm "Bad RAR file data"); 2904231200Smm return (ARCHIVE_FATAL); 2905231200Smm } 2906231200Smm if (firstpart < length) { 2907231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], 2908231200Smm &rar->lzss.window[windowoffs], firstpart); 2909231200Smm memcpy(&rar->unp_buffer[rar->unp_offset + firstpart], 2910231200Smm &rar->lzss.window[0], length - firstpart); 2911302075Smm } else { 2912231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], 2913231200Smm &rar->lzss.window[windowoffs], length); 2914302075Smm } 2915302075Smm } else { 2916302075Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2917302075Smm "Bad RAR file data"); 2918302075Smm return (ARCHIVE_FATAL); 2919231200Smm } 2920231200Smm rar->unp_offset += length; 2921231200Smm if (rar->unp_offset >= rar->unp_buffer_size) 2922231200Smm *buffer = rar->unp_buffer; 2923231200Smm else 2924231200Smm *buffer = NULL; 2925231200Smm return (ARCHIVE_OK); 2926231200Smm} 2927248616Smm 2928248616Smmstatic const void * 2929248616Smmrar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail) 2930248616Smm{ 2931248616Smm struct rar *rar = (struct rar *)(a->format->data); 2932248616Smm const void *h = __archive_read_ahead(a, min, avail); 2933248616Smm int ret; 2934248616Smm if (avail) 2935248616Smm { 2936299529Smm if (a->archive.read_data_is_posix_read && *avail > (ssize_t)a->archive.read_data_requested) 2937299529Smm *avail = a->archive.read_data_requested; 2938248616Smm if (*avail > rar->bytes_remaining) 2939248616Smm *avail = (ssize_t)rar->bytes_remaining; 2940248616Smm if (*avail < 0) 2941248616Smm return NULL; 2942248616Smm else if (*avail == 0 && rar->main_flags & MHD_VOLUME && 2943248616Smm rar->file_flags & FHD_SPLIT_AFTER) 2944248616Smm { 2945342360Smm rar->filename_must_match = 1; 2946248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 2947248616Smm if (ret == (ARCHIVE_EOF)) 2948248616Smm { 2949248616Smm rar->has_endarc_header = 1; 2950248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 2951248616Smm } 2952342360Smm rar->filename_must_match = 0; 2953248616Smm if (ret != (ARCHIVE_OK)) 2954248616Smm return NULL; 2955248616Smm return rar_read_ahead(a, min, avail); 2956248616Smm } 2957248616Smm } 2958248616Smm return h; 2959248616Smm} 2960