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 151358088Smm#undef minimum 152358088Smm#define minimum(a, b) ((a)<(b)?(a):(b)) 153358088Smm 154368707Smm/* Stack overflow check */ 155368707Smm#define MAX_COMPRESS_DEPTH 1024 156368707Smm 157231200Smm/* Fields common to all headers */ 158231200Smmstruct rar_header 159231200Smm{ 160231200Smm char crc[2]; 161231200Smm char type; 162231200Smm char flags[2]; 163231200Smm char size[2]; 164231200Smm}; 165231200Smm 166231200Smm/* Fields common to all file headers */ 167231200Smmstruct rar_file_header 168231200Smm{ 169231200Smm char pack_size[4]; 170231200Smm char unp_size[4]; 171231200Smm char host_os; 172231200Smm char file_crc[4]; 173231200Smm char file_time[4]; 174231200Smm char unp_ver; 175231200Smm char method; 176231200Smm char name_size[2]; 177231200Smm char file_attr[4]; 178231200Smm}; 179231200Smm 180231200Smmstruct huffman_tree_node 181231200Smm{ 182231200Smm int branches[2]; 183231200Smm}; 184231200Smm 185231200Smmstruct huffman_table_entry 186231200Smm{ 187231200Smm unsigned int length; 188231200Smm int value; 189231200Smm}; 190231200Smm 191231200Smmstruct huffman_code 192231200Smm{ 193231200Smm struct huffman_tree_node *tree; 194231200Smm int numentries; 195299529Smm int numallocatedentries; 196231200Smm int minlength; 197231200Smm int maxlength; 198231200Smm int tablesize; 199231200Smm struct huffman_table_entry *table; 200231200Smm}; 201231200Smm 202231200Smmstruct lzss 203231200Smm{ 204231200Smm unsigned char *window; 205231200Smm int mask; 206231200Smm int64_t position; 207231200Smm}; 208231200Smm 209248616Smmstruct data_block_offsets 210248616Smm{ 211248616Smm int64_t header_size; 212248616Smm int64_t start_offset; 213248616Smm int64_t end_offset; 214248616Smm}; 215248616Smm 216231200Smmstruct rar 217231200Smm{ 218231200Smm /* Entries from main RAR header */ 219231200Smm unsigned main_flags; 220231200Smm unsigned long file_crc; 221231200Smm char reserved1[2]; 222231200Smm char reserved2[4]; 223231200Smm char encryptver; 224231200Smm 225231200Smm /* File header entries */ 226231200Smm char compression_method; 227231200Smm unsigned file_flags; 228231200Smm int64_t packed_size; 229231200Smm int64_t unp_size; 230231200Smm time_t mtime; 231231200Smm long mnsec; 232231200Smm mode_t mode; 233231200Smm char *filename; 234248616Smm char *filename_save; 235299529Smm size_t filename_save_size; 236231200Smm size_t filename_allocated; 237231200Smm 238231200Smm /* File header optional entries */ 239231200Smm char salt[8]; 240231200Smm time_t atime; 241231200Smm long ansec; 242231200Smm time_t ctime; 243231200Smm long cnsec; 244231200Smm time_t arctime; 245231200Smm long arcnsec; 246231200Smm 247231200Smm /* Fields to help with tracking decompression of files. */ 248231200Smm int64_t bytes_unconsumed; 249231200Smm int64_t bytes_remaining; 250231200Smm int64_t bytes_uncopied; 251231200Smm int64_t offset; 252231200Smm int64_t offset_outgoing; 253248616Smm int64_t offset_seek; 254231200Smm char valid; 255231200Smm unsigned int unp_offset; 256231200Smm unsigned int unp_buffer_size; 257231200Smm unsigned char *unp_buffer; 258231200Smm unsigned int dictionary_size; 259231200Smm char start_new_block; 260231200Smm char entry_eof; 261231200Smm unsigned long crc_calculated; 262231200Smm int found_first_header; 263248616Smm char has_endarc_header; 264248616Smm struct data_block_offsets *dbo; 265248616Smm unsigned int cursor; 266248616Smm unsigned int nodes; 267342360Smm char filename_must_match; 268231200Smm 269231200Smm /* LZSS members */ 270231200Smm struct huffman_code maincode; 271231200Smm struct huffman_code offsetcode; 272231200Smm struct huffman_code lowoffsetcode; 273231200Smm struct huffman_code lengthcode; 274231200Smm unsigned char lengthtable[HUFFMAN_TABLE_SIZE]; 275231200Smm struct lzss lzss; 276231200Smm char output_last_match; 277231200Smm unsigned int lastlength; 278231200Smm unsigned int lastoffset; 279231200Smm unsigned int oldoffset[4]; 280231200Smm unsigned int lastlowoffset; 281231200Smm unsigned int numlowoffsetrepeats; 282231200Smm int64_t filterstart; 283231200Smm char start_new_table; 284231200Smm 285231200Smm /* PPMd Variant H members */ 286231200Smm char ppmd_valid; 287231200Smm char ppmd_eod; 288231200Smm char is_ppmd_block; 289231200Smm int ppmd_escape; 290231200Smm CPpmd7 ppmd7_context; 291231200Smm CPpmd7z_RangeDec range_dec; 292231200Smm IByteIn bytein; 293231200Smm 294231200Smm /* 295231200Smm * String conversion object. 296231200Smm */ 297231200Smm int init_default_conversion; 298231200Smm struct archive_string_conv *sconv_default; 299231200Smm struct archive_string_conv *opt_sconv; 300231200Smm struct archive_string_conv *sconv_utf8; 301231200Smm struct archive_string_conv *sconv_utf16be; 302231200Smm 303231200Smm /* 304231200Smm * Bit stream reader. 305231200Smm */ 306231200Smm struct rar_br { 307231200Smm#define CACHE_TYPE uint64_t 308231200Smm#define CACHE_BITS (8 * sizeof(CACHE_TYPE)) 309231200Smm /* Cache buffer. */ 310231200Smm CACHE_TYPE cache_buffer; 311231200Smm /* Indicates how many bits avail in cache_buffer. */ 312231200Smm int cache_avail; 313231200Smm ssize_t avail_in; 314231200Smm const unsigned char *next_in; 315231200Smm } br; 316299529Smm 317299529Smm /* 318299529Smm * Custom field to denote that this archive contains encrypted entries 319299529Smm */ 320299529Smm int has_encrypted_entries; 321231200Smm}; 322231200Smm 323299529Smmstatic int archive_read_support_format_rar_capabilities(struct archive_read *); 324299529Smmstatic int archive_read_format_rar_has_encrypted_entries(struct archive_read *); 325231200Smmstatic int archive_read_format_rar_bid(struct archive_read *, int); 326231200Smmstatic int archive_read_format_rar_options(struct archive_read *, 327231200Smm const char *, const char *); 328231200Smmstatic int archive_read_format_rar_read_header(struct archive_read *, 329231200Smm struct archive_entry *); 330231200Smmstatic int archive_read_format_rar_read_data(struct archive_read *, 331231200Smm const void **, size_t *, int64_t *); 332231200Smmstatic int archive_read_format_rar_read_data_skip(struct archive_read *a); 333248616Smmstatic int64_t archive_read_format_rar_seek_data(struct archive_read *, int64_t, 334248616Smm int); 335231200Smmstatic int archive_read_format_rar_cleanup(struct archive_read *); 336231200Smm 337231200Smm/* Support functions */ 338231200Smmstatic int read_header(struct archive_read *, struct archive_entry *, char); 339232153Smmstatic time_t get_time(int); 340231200Smmstatic int read_exttime(const char *, struct rar *, const char *); 341231200Smmstatic int read_symlink_stored(struct archive_read *, struct archive_entry *, 342231200Smm struct archive_string_conv *); 343231200Smmstatic int read_data_stored(struct archive_read *, const void **, size_t *, 344231200Smm int64_t *); 345231200Smmstatic int read_data_compressed(struct archive_read *, const void **, size_t *, 346368707Smm int64_t *, size_t); 347231200Smmstatic int rar_br_preparation(struct archive_read *, struct rar_br *); 348231200Smmstatic int parse_codes(struct archive_read *); 349231200Smmstatic void free_codes(struct archive_read *); 350231200Smmstatic int read_next_symbol(struct archive_read *, struct huffman_code *); 351231200Smmstatic int create_code(struct archive_read *, struct huffman_code *, 352231200Smm unsigned char *, int, char); 353231200Smmstatic int add_value(struct archive_read *, struct huffman_code *, int, int, 354231200Smm int); 355231200Smmstatic int new_node(struct huffman_code *); 356231200Smmstatic int make_table(struct archive_read *, struct huffman_code *); 357231200Smmstatic int make_table_recurse(struct archive_read *, struct huffman_code *, int, 358231200Smm struct huffman_table_entry *, int, int); 359231200Smmstatic int64_t expand(struct archive_read *, int64_t); 360231200Smmstatic int copy_from_lzss_window(struct archive_read *, const void **, 361231200Smm int64_t, int); 362248616Smmstatic const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *); 363231200Smm 364231200Smm/* 365231200Smm * Bit stream reader. 366231200Smm */ 367231200Smm/* Check that the cache buffer has enough bits. */ 368231200Smm#define rar_br_has(br, n) ((br)->cache_avail >= n) 369231200Smm/* Get compressed data by bit. */ 370231200Smm#define rar_br_bits(br, n) \ 371231200Smm (((uint32_t)((br)->cache_buffer >> \ 372231200Smm ((br)->cache_avail - (n)))) & cache_masks[n]) 373231200Smm#define rar_br_bits_forced(br, n) \ 374231200Smm (((uint32_t)((br)->cache_buffer << \ 375231200Smm ((n) - (br)->cache_avail))) & cache_masks[n]) 376231200Smm/* Read ahead to make sure the cache buffer has enough compressed data we 377231200Smm * will use. 378231200Smm * True : completed, there is enough data in the cache buffer. 379231200Smm * False : there is no data in the stream. */ 380231200Smm#define rar_br_read_ahead(a, br, n) \ 381231200Smm ((rar_br_has(br, (n)) || rar_br_fillup(a, br)) || rar_br_has(br, (n))) 382231200Smm/* Notify how many bits we consumed. */ 383231200Smm#define rar_br_consume(br, n) ((br)->cache_avail -= (n)) 384231200Smm#define rar_br_consume_unalined_bits(br) ((br)->cache_avail &= ~7) 385231200Smm 386231200Smmstatic const uint32_t cache_masks[] = { 387231200Smm 0x00000000, 0x00000001, 0x00000003, 0x00000007, 388231200Smm 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, 389231200Smm 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 390231200Smm 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 391231200Smm 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 392231200Smm 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 393231200Smm 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 394231200Smm 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 395231200Smm 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF 396231200Smm}; 397231200Smm 398231200Smm/* 399231200Smm * Shift away used bits in the cache data and fill it up with following bits. 400231200Smm * Call this when cache buffer does not have enough bits you need. 401231200Smm * 402231200Smm * Returns 1 if the cache buffer is full. 403231200Smm * Returns 0 if the cache buffer is not full; input buffer is empty. 404231200Smm */ 405231200Smmstatic int 406231200Smmrar_br_fillup(struct archive_read *a, struct rar_br *br) 407231200Smm{ 408231200Smm struct rar *rar = (struct rar *)(a->format->data); 409231200Smm int n = CACHE_BITS - br->cache_avail; 410231200Smm 411231200Smm for (;;) { 412231200Smm switch (n >> 3) { 413231200Smm case 8: 414231200Smm if (br->avail_in >= 8) { 415231200Smm br->cache_buffer = 416231200Smm ((uint64_t)br->next_in[0]) << 56 | 417231200Smm ((uint64_t)br->next_in[1]) << 48 | 418231200Smm ((uint64_t)br->next_in[2]) << 40 | 419231200Smm ((uint64_t)br->next_in[3]) << 32 | 420231200Smm ((uint32_t)br->next_in[4]) << 24 | 421231200Smm ((uint32_t)br->next_in[5]) << 16 | 422231200Smm ((uint32_t)br->next_in[6]) << 8 | 423231200Smm (uint32_t)br->next_in[7]; 424231200Smm br->next_in += 8; 425231200Smm br->avail_in -= 8; 426231200Smm br->cache_avail += 8 * 8; 427231200Smm rar->bytes_unconsumed += 8; 428231200Smm rar->bytes_remaining -= 8; 429231200Smm return (1); 430231200Smm } 431231200Smm break; 432231200Smm case 7: 433231200Smm if (br->avail_in >= 7) { 434231200Smm br->cache_buffer = 435231200Smm (br->cache_buffer << 56) | 436231200Smm ((uint64_t)br->next_in[0]) << 48 | 437231200Smm ((uint64_t)br->next_in[1]) << 40 | 438231200Smm ((uint64_t)br->next_in[2]) << 32 | 439231200Smm ((uint32_t)br->next_in[3]) << 24 | 440231200Smm ((uint32_t)br->next_in[4]) << 16 | 441231200Smm ((uint32_t)br->next_in[5]) << 8 | 442231200Smm (uint32_t)br->next_in[6]; 443231200Smm br->next_in += 7; 444231200Smm br->avail_in -= 7; 445231200Smm br->cache_avail += 7 * 8; 446231200Smm rar->bytes_unconsumed += 7; 447231200Smm rar->bytes_remaining -= 7; 448231200Smm return (1); 449231200Smm } 450231200Smm break; 451231200Smm case 6: 452231200Smm if (br->avail_in >= 6) { 453231200Smm br->cache_buffer = 454231200Smm (br->cache_buffer << 48) | 455231200Smm ((uint64_t)br->next_in[0]) << 40 | 456231200Smm ((uint64_t)br->next_in[1]) << 32 | 457231200Smm ((uint32_t)br->next_in[2]) << 24 | 458231200Smm ((uint32_t)br->next_in[3]) << 16 | 459231200Smm ((uint32_t)br->next_in[4]) << 8 | 460231200Smm (uint32_t)br->next_in[5]; 461231200Smm br->next_in += 6; 462231200Smm br->avail_in -= 6; 463231200Smm br->cache_avail += 6 * 8; 464231200Smm rar->bytes_unconsumed += 6; 465231200Smm rar->bytes_remaining -= 6; 466231200Smm return (1); 467231200Smm } 468231200Smm break; 469231200Smm case 0: 470231200Smm /* We have enough compressed data in 471231200Smm * the cache buffer.*/ 472231200Smm return (1); 473231200Smm default: 474231200Smm break; 475231200Smm } 476231200Smm if (br->avail_in <= 0) { 477231200Smm 478231200Smm if (rar->bytes_unconsumed > 0) { 479231200Smm /* Consume as much as the decompressor 480231200Smm * actually used. */ 481231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 482231200Smm rar->bytes_unconsumed = 0; 483231200Smm } 484248616Smm br->next_in = rar_read_ahead(a, 1, &(br->avail_in)); 485231200Smm if (br->next_in == NULL) 486231200Smm return (0); 487231200Smm if (br->avail_in == 0) 488231200Smm return (0); 489231200Smm } 490231200Smm br->cache_buffer = 491231200Smm (br->cache_buffer << 8) | *br->next_in++; 492231200Smm br->avail_in--; 493231200Smm br->cache_avail += 8; 494231200Smm n -= 8; 495231200Smm rar->bytes_unconsumed++; 496231200Smm rar->bytes_remaining--; 497231200Smm } 498231200Smm} 499231200Smm 500231200Smmstatic int 501231200Smmrar_br_preparation(struct archive_read *a, struct rar_br *br) 502231200Smm{ 503231200Smm struct rar *rar = (struct rar *)(a->format->data); 504231200Smm 505231200Smm if (rar->bytes_remaining > 0) { 506248616Smm br->next_in = rar_read_ahead(a, 1, &(br->avail_in)); 507231200Smm if (br->next_in == NULL) { 508231200Smm archive_set_error(&a->archive, 509231200Smm ARCHIVE_ERRNO_FILE_FORMAT, 510231200Smm "Truncated RAR file data"); 511231200Smm return (ARCHIVE_FATAL); 512231200Smm } 513231200Smm if (br->cache_avail == 0) 514231200Smm (void)rar_br_fillup(a, br); 515231200Smm } 516231200Smm return (ARCHIVE_OK); 517231200Smm} 518231200Smm 519231200Smm/* Find last bit set */ 520231200Smmstatic inline int 521231200Smmrar_fls(unsigned int word) 522231200Smm{ 523231200Smm word |= (word >> 1); 524231200Smm word |= (word >> 2); 525231200Smm word |= (word >> 4); 526231200Smm word |= (word >> 8); 527231200Smm word |= (word >> 16); 528231200Smm return word - (word >> 1); 529231200Smm} 530231200Smm 531231200Smm/* LZSS functions */ 532231200Smmstatic inline int64_t 533231200Smmlzss_position(struct lzss *lzss) 534231200Smm{ 535231200Smm return lzss->position; 536231200Smm} 537231200Smm 538231200Smmstatic inline int 539231200Smmlzss_mask(struct lzss *lzss) 540231200Smm{ 541231200Smm return lzss->mask; 542231200Smm} 543231200Smm 544231200Smmstatic inline int 545231200Smmlzss_size(struct lzss *lzss) 546231200Smm{ 547231200Smm return lzss->mask + 1; 548231200Smm} 549231200Smm 550231200Smmstatic inline int 551231200Smmlzss_offset_for_position(struct lzss *lzss, int64_t pos) 552231200Smm{ 553238856Smm return (int)(pos & lzss->mask); 554231200Smm} 555231200Smm 556231200Smmstatic inline unsigned char * 557231200Smmlzss_pointer_for_position(struct lzss *lzss, int64_t pos) 558231200Smm{ 559231200Smm return &lzss->window[lzss_offset_for_position(lzss, pos)]; 560231200Smm} 561231200Smm 562231200Smmstatic inline int 563231200Smmlzss_current_offset(struct lzss *lzss) 564231200Smm{ 565231200Smm return lzss_offset_for_position(lzss, lzss->position); 566231200Smm} 567231200Smm 568231200Smmstatic inline uint8_t * 569231200Smmlzss_current_pointer(struct lzss *lzss) 570231200Smm{ 571231200Smm return lzss_pointer_for_position(lzss, lzss->position); 572231200Smm} 573231200Smm 574231200Smmstatic inline void 575231200Smmlzss_emit_literal(struct rar *rar, uint8_t literal) 576231200Smm{ 577231200Smm *lzss_current_pointer(&rar->lzss) = literal; 578231200Smm rar->lzss.position++; 579231200Smm} 580231200Smm 581231200Smmstatic inline void 582231200Smmlzss_emit_match(struct rar *rar, int offset, int length) 583231200Smm{ 584231200Smm int dstoffs = lzss_current_offset(&rar->lzss); 585231200Smm int srcoffs = (dstoffs - offset) & lzss_mask(&rar->lzss); 586231200Smm int l, li, remaining; 587231200Smm unsigned char *d, *s; 588231200Smm 589231200Smm remaining = length; 590231200Smm while (remaining > 0) { 591231200Smm l = remaining; 592231200Smm if (dstoffs > srcoffs) { 593231200Smm if (l > lzss_size(&rar->lzss) - dstoffs) 594231200Smm l = lzss_size(&rar->lzss) - dstoffs; 595231200Smm } else { 596231200Smm if (l > lzss_size(&rar->lzss) - srcoffs) 597231200Smm l = lzss_size(&rar->lzss) - srcoffs; 598231200Smm } 599231200Smm d = &(rar->lzss.window[dstoffs]); 600231200Smm s = &(rar->lzss.window[srcoffs]); 601231200Smm if ((dstoffs + l < srcoffs) || (srcoffs + l < dstoffs)) 602231200Smm memcpy(d, s, l); 603231200Smm else { 604231200Smm for (li = 0; li < l; li++) 605231200Smm d[li] = s[li]; 606231200Smm } 607231200Smm remaining -= l; 608231200Smm dstoffs = (dstoffs + l) & lzss_mask(&(rar->lzss)); 609231200Smm srcoffs = (srcoffs + l) & lzss_mask(&(rar->lzss)); 610231200Smm } 611231200Smm rar->lzss.position += length; 612231200Smm} 613231200Smm 614231200Smmstatic Byte 615231200Smmppmd_read(void *p) 616231200Smm{ 617231200Smm struct archive_read *a = ((IByteIn*)p)->a; 618231200Smm struct rar *rar = (struct rar *)(a->format->data); 619231200Smm struct rar_br *br = &(rar->br); 620231200Smm Byte b; 621231200Smm if (!rar_br_read_ahead(a, br, 8)) 622231200Smm { 623231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 624231200Smm "Truncated RAR file data"); 625231200Smm rar->valid = 0; 626231200Smm return 0; 627231200Smm } 628231200Smm b = rar_br_bits(br, 8); 629231200Smm rar_br_consume(br, 8); 630231200Smm return b; 631231200Smm} 632231200Smm 633231200Smmint 634231200Smmarchive_read_support_format_rar(struct archive *_a) 635231200Smm{ 636231200Smm struct archive_read *a = (struct archive_read *)_a; 637231200Smm struct rar *rar; 638231200Smm int r; 639231200Smm 640231200Smm archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, 641231200Smm "archive_read_support_format_rar"); 642231200Smm 643311041Smm rar = (struct rar *)calloc(sizeof(*rar), 1); 644231200Smm if (rar == NULL) 645231200Smm { 646231200Smm archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data"); 647231200Smm return (ARCHIVE_FATAL); 648231200Smm } 649231200Smm 650299529Smm /* 651299529Smm * Until enough data has been read, we cannot tell about 652299529Smm * any encrypted entries yet. 653299529Smm */ 654299529Smm rar->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; 655299529Smm 656231200Smm r = __archive_read_register_format(a, 657231200Smm rar, 658231200Smm "rar", 659231200Smm archive_read_format_rar_bid, 660231200Smm archive_read_format_rar_options, 661231200Smm archive_read_format_rar_read_header, 662231200Smm archive_read_format_rar_read_data, 663231200Smm archive_read_format_rar_read_data_skip, 664248616Smm archive_read_format_rar_seek_data, 665299529Smm archive_read_format_rar_cleanup, 666299529Smm archive_read_support_format_rar_capabilities, 667299529Smm archive_read_format_rar_has_encrypted_entries); 668231200Smm 669231200Smm if (r != ARCHIVE_OK) 670231200Smm free(rar); 671231200Smm return (r); 672231200Smm} 673231200Smm 674231200Smmstatic int 675299529Smmarchive_read_support_format_rar_capabilities(struct archive_read * a) 676299529Smm{ 677299529Smm (void)a; /* UNUSED */ 678299529Smm return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA 679299529Smm | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA); 680299529Smm} 681299529Smm 682299529Smmstatic int 683299529Smmarchive_read_format_rar_has_encrypted_entries(struct archive_read *_a) 684299529Smm{ 685299529Smm if (_a && _a->format) { 686299529Smm struct rar * rar = (struct rar *)_a->format->data; 687299529Smm if (rar) { 688299529Smm return rar->has_encrypted_entries; 689299529Smm } 690299529Smm } 691299529Smm return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; 692299529Smm} 693299529Smm 694299529Smm 695299529Smmstatic int 696231200Smmarchive_read_format_rar_bid(struct archive_read *a, int best_bid) 697231200Smm{ 698231200Smm const char *p; 699231200Smm 700231200Smm /* If there's already a bid > 30, we'll never win. */ 701231200Smm if (best_bid > 30) 702231200Smm return (-1); 703231200Smm 704231200Smm if ((p = __archive_read_ahead(a, 7, NULL)) == NULL) 705231200Smm return (-1); 706231200Smm 707231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) 708231200Smm return (30); 709231200Smm 710231200Smm if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) { 711231200Smm /* This is a PE file */ 712231200Smm ssize_t offset = 0x10000; 713231200Smm ssize_t window = 4096; 714231200Smm ssize_t bytes_avail; 715231200Smm while (offset + window <= (1024 * 128)) { 716231200Smm const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail); 717231200Smm if (buff == NULL) { 718231200Smm /* Remaining bytes are less than window. */ 719231200Smm window >>= 1; 720231200Smm if (window < 0x40) 721231200Smm return (0); 722231200Smm continue; 723231200Smm } 724231200Smm p = buff + offset; 725231200Smm while (p + 7 < buff + bytes_avail) { 726231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) 727231200Smm return (30); 728231200Smm p += 0x10; 729231200Smm } 730231200Smm offset = p - buff; 731231200Smm } 732231200Smm } 733231200Smm return (0); 734231200Smm} 735231200Smm 736231200Smmstatic int 737231200Smmskip_sfx(struct archive_read *a) 738231200Smm{ 739231200Smm const void *h; 740231200Smm const char *p, *q; 741231200Smm size_t skip, total; 742231200Smm ssize_t bytes, window; 743231200Smm 744231200Smm total = 0; 745231200Smm window = 4096; 746231200Smm while (total + window <= (1024 * 128)) { 747231200Smm h = __archive_read_ahead(a, window, &bytes); 748231200Smm if (h == NULL) { 749231200Smm /* Remaining bytes are less than window. */ 750231200Smm window >>= 1; 751231200Smm if (window < 0x40) 752231200Smm goto fatal; 753231200Smm continue; 754231200Smm } 755231200Smm if (bytes < 0x40) 756231200Smm goto fatal; 757231200Smm p = h; 758231200Smm q = p + bytes; 759231200Smm 760231200Smm /* 761231200Smm * Scan ahead until we find something that looks 762231200Smm * like the RAR header. 763231200Smm */ 764231200Smm while (p + 7 < q) { 765231200Smm if (memcmp(p, RAR_SIGNATURE, 7) == 0) { 766231200Smm skip = p - (const char *)h; 767231200Smm __archive_read_consume(a, skip); 768231200Smm return (ARCHIVE_OK); 769231200Smm } 770231200Smm p += 0x10; 771231200Smm } 772231200Smm skip = p - (const char *)h; 773231200Smm __archive_read_consume(a, skip); 774231200Smm total += skip; 775231200Smm } 776231200Smmfatal: 777231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 778231200Smm "Couldn't find out RAR header"); 779231200Smm return (ARCHIVE_FATAL); 780231200Smm} 781231200Smm 782231200Smmstatic int 783231200Smmarchive_read_format_rar_options(struct archive_read *a, 784231200Smm const char *key, const char *val) 785231200Smm{ 786231200Smm struct rar *rar; 787231200Smm int ret = ARCHIVE_FAILED; 788299529Smm 789231200Smm rar = (struct rar *)(a->format->data); 790231200Smm if (strcmp(key, "hdrcharset") == 0) { 791231200Smm if (val == NULL || val[0] == 0) 792231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 793231200Smm "rar: hdrcharset option needs a character-set name"); 794231200Smm else { 795231200Smm rar->opt_sconv = 796231200Smm archive_string_conversion_from_charset( 797231200Smm &a->archive, val, 0); 798231200Smm if (rar->opt_sconv != NULL) 799231200Smm ret = ARCHIVE_OK; 800231200Smm else 801231200Smm ret = ARCHIVE_FATAL; 802231200Smm } 803232153Smm return (ret); 804232153Smm } 805232153Smm 806232153Smm /* Note: The "warn" return is just to inform the options 807232153Smm * supervisor that we didn't handle it. It will generate 808232153Smm * a suitable error if no one used this option. */ 809232153Smm return (ARCHIVE_WARN); 810231200Smm} 811231200Smm 812231200Smmstatic int 813231200Smmarchive_read_format_rar_read_header(struct archive_read *a, 814231200Smm struct archive_entry *entry) 815231200Smm{ 816231200Smm const void *h; 817231200Smm const char *p; 818231200Smm struct rar *rar; 819231200Smm size_t skip; 820231200Smm char head_type; 821231200Smm int ret; 822231200Smm unsigned flags; 823299529Smm unsigned long crc32_expected; 824231200Smm 825231200Smm a->archive.archive_format = ARCHIVE_FORMAT_RAR; 826231200Smm if (a->archive.archive_format_name == NULL) 827231200Smm a->archive.archive_format_name = "RAR"; 828231200Smm 829231200Smm rar = (struct rar *)(a->format->data); 830231200Smm 831299529Smm /* 832299529Smm * It should be sufficient to call archive_read_next_header() for 833299529Smm * a reader to determine if an entry is encrypted or not. If the 834299529Smm * encryption of an entry is only detectable when calling 835299529Smm * archive_read_data(), so be it. We'll do the same check there 836299529Smm * as well. 837299529Smm */ 838299529Smm if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { 839299529Smm rar->has_encrypted_entries = 0; 840299529Smm } 841299529Smm 842231200Smm /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if 843231200Smm * this fails. 844231200Smm */ 845231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 846231200Smm return (ARCHIVE_EOF); 847231200Smm 848231200Smm p = h; 849231200Smm if (rar->found_first_header == 0 && 850231200Smm ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) { 851231200Smm /* This is an executable ? Must be self-extracting... */ 852231200Smm ret = skip_sfx(a); 853231200Smm if (ret < ARCHIVE_WARN) 854231200Smm return (ret); 855231200Smm } 856231200Smm rar->found_first_header = 1; 857231200Smm 858231200Smm while (1) 859231200Smm { 860231200Smm unsigned long crc32_val; 861231200Smm 862231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 863231200Smm return (ARCHIVE_FATAL); 864231200Smm p = h; 865231200Smm 866231200Smm head_type = p[2]; 867231200Smm switch(head_type) 868231200Smm { 869231200Smm case MARK_HEAD: 870231200Smm if (memcmp(p, RAR_SIGNATURE, 7) != 0) { 871231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 872231200Smm "Invalid marker header"); 873231200Smm return (ARCHIVE_FATAL); 874231200Smm } 875231200Smm __archive_read_consume(a, 7); 876231200Smm break; 877231200Smm 878231200Smm case MAIN_HEAD: 879231200Smm rar->main_flags = archive_le16dec(p + 3); 880231200Smm skip = archive_le16dec(p + 5); 881231200Smm if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) { 882231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 883231200Smm "Invalid header size"); 884231200Smm return (ARCHIVE_FATAL); 885231200Smm } 886231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 887231200Smm return (ARCHIVE_FATAL); 888231200Smm p = h; 889231200Smm memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1)); 890231200Smm memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1), 891231200Smm sizeof(rar->reserved2)); 892231200Smm if (rar->main_flags & MHD_ENCRYPTVER) { 893231200Smm if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) { 894231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 895231200Smm "Invalid header size"); 896231200Smm return (ARCHIVE_FATAL); 897231200Smm } 898231200Smm rar->encryptver = *(p + 7 + sizeof(rar->reserved1) + 899231200Smm sizeof(rar->reserved2)); 900231200Smm } 901231200Smm 902313570Smm /* Main header is password encrypted, so we cannot read any 903299529Smm file names or any other info about files from the header. */ 904231200Smm if (rar->main_flags & MHD_PASSWORD) 905231200Smm { 906299529Smm archive_entry_set_is_metadata_encrypted(entry, 1); 907299529Smm archive_entry_set_is_data_encrypted(entry, 1); 908299529Smm rar->has_encrypted_entries = 1; 909299529Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 910231200Smm "RAR encryption support unavailable."); 911231200Smm return (ARCHIVE_FATAL); 912231200Smm } 913231200Smm 914248616Smm crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2); 915231200Smm if ((crc32_val & 0xffff) != archive_le16dec(p)) { 916231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 917231200Smm "Header CRC error"); 918231200Smm return (ARCHIVE_FATAL); 919231200Smm } 920231200Smm __archive_read_consume(a, skip); 921231200Smm break; 922231200Smm 923231200Smm case FILE_HEAD: 924231200Smm return read_header(a, entry, head_type); 925231200Smm 926231200Smm case COMM_HEAD: 927231200Smm case AV_HEAD: 928231200Smm case SUB_HEAD: 929231200Smm case PROTECT_HEAD: 930231200Smm case SIGN_HEAD: 931248616Smm case ENDARC_HEAD: 932231200Smm flags = archive_le16dec(p + 3); 933231200Smm skip = archive_le16dec(p + 5); 934231200Smm if (skip < 7) { 935231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 936299529Smm "Invalid header size too small"); 937231200Smm return (ARCHIVE_FATAL); 938231200Smm } 939231200Smm if (flags & HD_ADD_SIZE_PRESENT) 940231200Smm { 941231200Smm if (skip < 7 + 4) { 942231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 943299529Smm "Invalid header size too small"); 944231200Smm return (ARCHIVE_FATAL); 945231200Smm } 946231200Smm if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) 947231200Smm return (ARCHIVE_FATAL); 948231200Smm p = h; 949299529Smm skip += archive_le32dec(p + 7); 950231200Smm } 951231200Smm 952299529Smm /* Skip over the 2-byte CRC at the beginning of the header. */ 953299529Smm crc32_expected = archive_le16dec(p); 954299529Smm __archive_read_consume(a, 2); 955299529Smm skip -= 2; 956299529Smm 957299529Smm /* Skim the entire header and compute the CRC. */ 958299529Smm crc32_val = 0; 959299529Smm while (skip > 0) { 960299529Smm size_t to_read = skip; 961370535Sgit2svn if (to_read > 32 * 1024) 962299529Smm to_read = 32 * 1024; 963370535Sgit2svn if ((h = __archive_read_ahead(a, to_read, NULL)) == NULL) { 964370535Sgit2svn archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 965370535Sgit2svn "Bad RAR file"); 966299529Smm return (ARCHIVE_FATAL); 967299529Smm } 968299529Smm p = h; 969370535Sgit2svn crc32_val = crc32(crc32_val, (const unsigned char *)p, to_read); 970370535Sgit2svn __archive_read_consume(a, to_read); 971370535Sgit2svn skip -= to_read; 972231200Smm } 973299529Smm if ((crc32_val & 0xffff) != crc32_expected) { 974299529Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 975299529Smm "Header CRC error"); 976299529Smm return (ARCHIVE_FATAL); 977299529Smm } 978248616Smm if (head_type == ENDARC_HEAD) 979299529Smm return (ARCHIVE_EOF); 980231200Smm break; 981231200Smm 982231200Smm case NEWSUB_HEAD: 983231200Smm if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN) 984231200Smm return ret; 985231200Smm break; 986231200Smm 987231200Smm default: 988231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 989231200Smm "Bad RAR file"); 990231200Smm return (ARCHIVE_FATAL); 991231200Smm } 992231200Smm } 993231200Smm} 994231200Smm 995231200Smmstatic int 996231200Smmarchive_read_format_rar_read_data(struct archive_read *a, const void **buff, 997231200Smm size_t *size, int64_t *offset) 998231200Smm{ 999231200Smm struct rar *rar = (struct rar *)(a->format->data); 1000231200Smm int ret; 1001231200Smm 1002299529Smm if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { 1003299529Smm rar->has_encrypted_entries = 0; 1004299529Smm } 1005299529Smm 1006231200Smm if (rar->bytes_unconsumed > 0) { 1007231200Smm /* Consume as much as the decompressor actually used. */ 1008231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 1009231200Smm rar->bytes_unconsumed = 0; 1010231200Smm } 1011231200Smm 1012299529Smm *buff = NULL; 1013248616Smm if (rar->entry_eof || rar->offset_seek >= rar->unp_size) { 1014231200Smm *size = 0; 1015231200Smm *offset = rar->offset; 1016248616Smm if (*offset < rar->unp_size) 1017248616Smm *offset = rar->unp_size; 1018231200Smm return (ARCHIVE_EOF); 1019231200Smm } 1020231200Smm 1021231200Smm switch (rar->compression_method) 1022231200Smm { 1023231200Smm case COMPRESS_METHOD_STORE: 1024231200Smm ret = read_data_stored(a, buff, size, offset); 1025299529Smm break; 1026231200Smm 1027231200Smm case COMPRESS_METHOD_FASTEST: 1028231200Smm case COMPRESS_METHOD_FAST: 1029231200Smm case COMPRESS_METHOD_NORMAL: 1030231200Smm case COMPRESS_METHOD_GOOD: 1031231200Smm case COMPRESS_METHOD_BEST: 1032368707Smm ret = read_data_compressed(a, buff, size, offset, 0); 1033348607Smm if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) { 1034328827Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); 1035348607Smm rar->start_new_table = 1; 1036349524Smm rar->ppmd_valid = 0; 1037348607Smm } 1038299529Smm break; 1039231200Smm 1040231200Smm default: 1041231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1042231200Smm "Unsupported compression method for RAR file."); 1043231200Smm ret = ARCHIVE_FATAL; 1044299529Smm break; 1045231200Smm } 1046231200Smm return (ret); 1047231200Smm} 1048231200Smm 1049231200Smmstatic int 1050231200Smmarchive_read_format_rar_read_data_skip(struct archive_read *a) 1051231200Smm{ 1052231200Smm struct rar *rar; 1053231200Smm int64_t bytes_skipped; 1054248616Smm int ret; 1055231200Smm 1056231200Smm rar = (struct rar *)(a->format->data); 1057231200Smm 1058231200Smm if (rar->bytes_unconsumed > 0) { 1059231200Smm /* Consume as much as the decompressor actually used. */ 1060231200Smm __archive_read_consume(a, rar->bytes_unconsumed); 1061231200Smm rar->bytes_unconsumed = 0; 1062231200Smm } 1063231200Smm 1064231200Smm if (rar->bytes_remaining > 0) { 1065231200Smm bytes_skipped = __archive_read_consume(a, rar->bytes_remaining); 1066231200Smm if (bytes_skipped < 0) 1067231200Smm return (ARCHIVE_FATAL); 1068231200Smm } 1069248616Smm 1070248616Smm /* Compressed data to skip must be read from each header in a multivolume 1071248616Smm * archive. 1072248616Smm */ 1073248616Smm if (rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER) 1074248616Smm { 1075248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1076248616Smm if (ret == (ARCHIVE_EOF)) 1077248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1078248616Smm if (ret != (ARCHIVE_OK)) 1079248616Smm return ret; 1080248616Smm return archive_read_format_rar_read_data_skip(a); 1081248616Smm } 1082248616Smm 1083231200Smm return (ARCHIVE_OK); 1084231200Smm} 1085231200Smm 1086248616Smmstatic int64_t 1087248616Smmarchive_read_format_rar_seek_data(struct archive_read *a, int64_t offset, 1088248616Smm int whence) 1089248616Smm{ 1090248616Smm int64_t client_offset, ret; 1091248616Smm unsigned int i; 1092248616Smm struct rar *rar = (struct rar *)(a->format->data); 1093248616Smm 1094248616Smm if (rar->compression_method == COMPRESS_METHOD_STORE) 1095248616Smm { 1096248616Smm /* Modify the offset for use with SEEK_SET */ 1097248616Smm switch (whence) 1098248616Smm { 1099248616Smm case SEEK_CUR: 1100248616Smm client_offset = rar->offset_seek; 1101248616Smm break; 1102248616Smm case SEEK_END: 1103248616Smm client_offset = rar->unp_size; 1104248616Smm break; 1105248616Smm case SEEK_SET: 1106248616Smm default: 1107248616Smm client_offset = 0; 1108248616Smm } 1109248616Smm client_offset += offset; 1110248616Smm if (client_offset < 0) 1111248616Smm { 1112248616Smm /* Can't seek past beginning of data block */ 1113248616Smm return -1; 1114248616Smm } 1115248616Smm else if (client_offset > rar->unp_size) 1116248616Smm { 1117248616Smm /* 1118248616Smm * Set the returned offset but only seek to the end of 1119248616Smm * the data block. 1120248616Smm */ 1121248616Smm rar->offset_seek = client_offset; 1122248616Smm client_offset = rar->unp_size; 1123248616Smm } 1124248616Smm 1125248616Smm client_offset += rar->dbo[0].start_offset; 1126248616Smm i = 0; 1127248616Smm while (i < rar->cursor) 1128248616Smm { 1129248616Smm i++; 1130248616Smm client_offset += rar->dbo[i].start_offset - rar->dbo[i-1].end_offset; 1131248616Smm } 1132248616Smm if (rar->main_flags & MHD_VOLUME) 1133248616Smm { 1134248616Smm /* Find the appropriate offset among the multivolume archive */ 1135248616Smm while (1) 1136248616Smm { 1137248616Smm if (client_offset < rar->dbo[rar->cursor].start_offset && 1138248616Smm rar->file_flags & FHD_SPLIT_BEFORE) 1139248616Smm { 1140248616Smm /* Search backwards for the correct data block */ 1141248616Smm if (rar->cursor == 0) 1142248616Smm { 1143248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1144248616Smm "Attempt to seek past beginning of RAR data block"); 1145248616Smm return (ARCHIVE_FAILED); 1146248616Smm } 1147248616Smm rar->cursor--; 1148248616Smm client_offset -= rar->dbo[rar->cursor+1].start_offset - 1149248616Smm rar->dbo[rar->cursor].end_offset; 1150248616Smm if (client_offset < rar->dbo[rar->cursor].start_offset) 1151248616Smm continue; 1152248616Smm ret = __archive_read_seek(a, rar->dbo[rar->cursor].start_offset - 1153248616Smm rar->dbo[rar->cursor].header_size, SEEK_SET); 1154248616Smm if (ret < (ARCHIVE_OK)) 1155248616Smm return ret; 1156248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1157248616Smm if (ret != (ARCHIVE_OK)) 1158248616Smm { 1159248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1160248616Smm "Error during seek of RAR file"); 1161248616Smm return (ARCHIVE_FAILED); 1162248616Smm } 1163248616Smm rar->cursor--; 1164248616Smm break; 1165248616Smm } 1166248616Smm else if (client_offset > rar->dbo[rar->cursor].end_offset && 1167248616Smm rar->file_flags & FHD_SPLIT_AFTER) 1168248616Smm { 1169248616Smm /* Search forward for the correct data block */ 1170248616Smm rar->cursor++; 1171248616Smm if (rar->cursor < rar->nodes && 1172248616Smm client_offset > rar->dbo[rar->cursor].end_offset) 1173248616Smm { 1174248616Smm client_offset += rar->dbo[rar->cursor].start_offset - 1175248616Smm rar->dbo[rar->cursor-1].end_offset; 1176248616Smm continue; 1177248616Smm } 1178248616Smm rar->cursor--; 1179248616Smm ret = __archive_read_seek(a, rar->dbo[rar->cursor].end_offset, 1180248616Smm SEEK_SET); 1181248616Smm if (ret < (ARCHIVE_OK)) 1182248616Smm return ret; 1183248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1184248616Smm if (ret == (ARCHIVE_EOF)) 1185248616Smm { 1186248616Smm rar->has_endarc_header = 1; 1187248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 1188248616Smm } 1189248616Smm if (ret != (ARCHIVE_OK)) 1190248616Smm { 1191248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1192248616Smm "Error during seek of RAR file"); 1193248616Smm return (ARCHIVE_FAILED); 1194248616Smm } 1195248616Smm client_offset += rar->dbo[rar->cursor].start_offset - 1196248616Smm rar->dbo[rar->cursor-1].end_offset; 1197248616Smm continue; 1198248616Smm } 1199248616Smm break; 1200248616Smm } 1201248616Smm } 1202248616Smm 1203248616Smm ret = __archive_read_seek(a, client_offset, SEEK_SET); 1204248616Smm if (ret < (ARCHIVE_OK)) 1205248616Smm return ret; 1206248616Smm rar->bytes_remaining = rar->dbo[rar->cursor].end_offset - ret; 1207248616Smm i = rar->cursor; 1208248616Smm while (i > 0) 1209248616Smm { 1210248616Smm i--; 1211248616Smm ret -= rar->dbo[i+1].start_offset - rar->dbo[i].end_offset; 1212248616Smm } 1213248616Smm ret -= rar->dbo[0].start_offset; 1214248616Smm 1215248616Smm /* Always restart reading the file after a seek */ 1216299529Smm __archive_reset_read_data(&a->archive); 1217299529Smm 1218248616Smm rar->bytes_unconsumed = 0; 1219248616Smm rar->offset = 0; 1220248616Smm 1221248616Smm /* 1222248616Smm * If a seek past the end of file was requested, return the requested 1223248616Smm * offset. 1224248616Smm */ 1225248616Smm if (ret == rar->unp_size && rar->offset_seek > rar->unp_size) 1226248616Smm return rar->offset_seek; 1227248616Smm 1228248616Smm /* Return the new offset */ 1229248616Smm rar->offset_seek = ret; 1230248616Smm return rar->offset_seek; 1231248616Smm } 1232248616Smm else 1233248616Smm { 1234248616Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1235248616Smm "Seeking of compressed RAR files is unsupported"); 1236248616Smm } 1237248616Smm return (ARCHIVE_FAILED); 1238248616Smm} 1239248616Smm 1240231200Smmstatic int 1241231200Smmarchive_read_format_rar_cleanup(struct archive_read *a) 1242231200Smm{ 1243231200Smm struct rar *rar; 1244231200Smm 1245231200Smm rar = (struct rar *)(a->format->data); 1246231200Smm free_codes(a); 1247231200Smm free(rar->filename); 1248248616Smm free(rar->filename_save); 1249248616Smm free(rar->dbo); 1250231200Smm free(rar->unp_buffer); 1251231200Smm free(rar->lzss.window); 1252328827Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); 1253231200Smm free(rar); 1254231200Smm (a->format->data) = NULL; 1255231200Smm return (ARCHIVE_OK); 1256231200Smm} 1257231200Smm 1258231200Smmstatic int 1259231200Smmread_header(struct archive_read *a, struct archive_entry *entry, 1260231200Smm char head_type) 1261231200Smm{ 1262231200Smm const void *h; 1263231200Smm const char *p, *endp; 1264231200Smm struct rar *rar; 1265231200Smm struct rar_header rar_header; 1266231200Smm struct rar_file_header file_header; 1267231200Smm int64_t header_size; 1268231200Smm unsigned filename_size, end; 1269231200Smm char *filename; 1270231200Smm char *strp; 1271231200Smm char packed_size[8]; 1272231200Smm char unp_size[8]; 1273232153Smm int ttime; 1274231200Smm struct archive_string_conv *sconv, *fn_sconv; 1275231200Smm unsigned long crc32_val; 1276231200Smm int ret = (ARCHIVE_OK), ret2; 1277231200Smm 1278231200Smm rar = (struct rar *)(a->format->data); 1279231200Smm 1280231200Smm /* Setup a string conversion object for non-rar-unicode filenames. */ 1281231200Smm sconv = rar->opt_sconv; 1282231200Smm if (sconv == NULL) { 1283231200Smm if (!rar->init_default_conversion) { 1284231200Smm rar->sconv_default = 1285231200Smm archive_string_default_conversion_for_read( 1286231200Smm &(a->archive)); 1287231200Smm rar->init_default_conversion = 1; 1288231200Smm } 1289231200Smm sconv = rar->sconv_default; 1290231200Smm } 1291231200Smm 1292231200Smm 1293231200Smm if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) 1294231200Smm return (ARCHIVE_FATAL); 1295231200Smm p = h; 1296231200Smm memcpy(&rar_header, p, sizeof(rar_header)); 1297231200Smm rar->file_flags = archive_le16dec(rar_header.flags); 1298231200Smm header_size = archive_le16dec(rar_header.size); 1299232153Smm if (header_size < (int64_t)sizeof(file_header) + 7) { 1300231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1301231200Smm "Invalid header size"); 1302231200Smm return (ARCHIVE_FATAL); 1303231200Smm } 1304231200Smm crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2); 1305231200Smm __archive_read_consume(a, 7); 1306231200Smm 1307231200Smm if (!(rar->file_flags & FHD_SOLID)) 1308231200Smm { 1309231200Smm rar->compression_method = 0; 1310231200Smm rar->packed_size = 0; 1311231200Smm rar->unp_size = 0; 1312231200Smm rar->mtime = 0; 1313231200Smm rar->ctime = 0; 1314231200Smm rar->atime = 0; 1315231200Smm rar->arctime = 0; 1316231200Smm rar->mode = 0; 1317231200Smm memset(&rar->salt, 0, sizeof(rar->salt)); 1318231200Smm rar->atime = 0; 1319231200Smm rar->ansec = 0; 1320231200Smm rar->ctime = 0; 1321231200Smm rar->cnsec = 0; 1322231200Smm rar->mtime = 0; 1323231200Smm rar->mnsec = 0; 1324231200Smm rar->arctime = 0; 1325231200Smm rar->arcnsec = 0; 1326231200Smm } 1327231200Smm else 1328231200Smm { 1329231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1330231200Smm "RAR solid archive support unavailable."); 1331231200Smm return (ARCHIVE_FATAL); 1332231200Smm } 1333231200Smm 1334238856Smm if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL) 1335231200Smm return (ARCHIVE_FATAL); 1336231200Smm 1337231200Smm /* File Header CRC check. */ 1338238856Smm crc32_val = crc32(crc32_val, h, (unsigned)(header_size - 7)); 1339231200Smm if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) { 1340231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1341231200Smm "Header CRC error"); 1342231200Smm return (ARCHIVE_FATAL); 1343231200Smm } 1344231200Smm /* If no CRC error, Go on parsing File Header. */ 1345231200Smm p = h; 1346231200Smm endp = p + header_size - 7; 1347231200Smm memcpy(&file_header, p, sizeof(file_header)); 1348231200Smm p += sizeof(file_header); 1349231200Smm 1350231200Smm rar->compression_method = file_header.method; 1351231200Smm 1352232153Smm ttime = archive_le32dec(file_header.file_time); 1353232153Smm rar->mtime = get_time(ttime); 1354231200Smm 1355231200Smm rar->file_crc = archive_le32dec(file_header.file_crc); 1356231200Smm 1357231200Smm if (rar->file_flags & FHD_PASSWORD) 1358231200Smm { 1359299529Smm archive_entry_set_is_data_encrypted(entry, 1); 1360299529Smm rar->has_encrypted_entries = 1; 1361231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1362231200Smm "RAR encryption support unavailable."); 1363299529Smm /* Since it is only the data part itself that is encrypted we can at least 1364299529Smm extract information about the currently processed entry and don't need 1365299529Smm to return ARCHIVE_FATAL here. */ 1366299529Smm /*return (ARCHIVE_FATAL);*/ 1367231200Smm } 1368231200Smm 1369231200Smm if (rar->file_flags & FHD_LARGE) 1370231200Smm { 1371231200Smm memcpy(packed_size, file_header.pack_size, 4); 1372231200Smm memcpy(packed_size + 4, p, 4); /* High pack size */ 1373231200Smm p += 4; 1374231200Smm memcpy(unp_size, file_header.unp_size, 4); 1375231200Smm memcpy(unp_size + 4, p, 4); /* High unpack size */ 1376231200Smm p += 4; 1377231200Smm rar->packed_size = archive_le64dec(&packed_size); 1378231200Smm rar->unp_size = archive_le64dec(&unp_size); 1379231200Smm } 1380231200Smm else 1381231200Smm { 1382231200Smm rar->packed_size = archive_le32dec(file_header.pack_size); 1383231200Smm rar->unp_size = archive_le32dec(file_header.unp_size); 1384231200Smm } 1385231200Smm 1386231200Smm if (rar->packed_size < 0 || rar->unp_size < 0) 1387231200Smm { 1388231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1389231200Smm "Invalid sizes specified."); 1390231200Smm return (ARCHIVE_FATAL); 1391231200Smm } 1392231200Smm 1393248616Smm rar->bytes_remaining = rar->packed_size; 1394248616Smm 1395231200Smm /* TODO: RARv3 subblocks contain comments. For now the complete block is 1396231200Smm * consumed at the end. 1397231200Smm */ 1398231200Smm if (head_type == NEWSUB_HEAD) { 1399231200Smm size_t distance = p - (const char *)h; 1400231200Smm header_size += rar->packed_size; 1401231200Smm /* Make sure we have the extended data. */ 1402238856Smm if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL) 1403231200Smm return (ARCHIVE_FATAL); 1404231200Smm p = h; 1405231200Smm endp = p + header_size - 7; 1406231200Smm p += distance; 1407231200Smm } 1408231200Smm 1409231200Smm filename_size = archive_le16dec(file_header.name_size); 1410231200Smm if (p + filename_size > endp) { 1411231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1412231200Smm "Invalid filename size"); 1413231200Smm return (ARCHIVE_FATAL); 1414231200Smm } 1415238856Smm if (rar->filename_allocated < filename_size * 2 + 2) { 1416238856Smm char *newptr; 1417238856Smm size_t newsize = filename_size * 2 + 2; 1418238856Smm newptr = realloc(rar->filename, newsize); 1419238856Smm if (newptr == NULL) { 1420231200Smm archive_set_error(&a->archive, ENOMEM, 1421231200Smm "Couldn't allocate memory."); 1422231200Smm return (ARCHIVE_FATAL); 1423231200Smm } 1424238856Smm rar->filename = newptr; 1425238856Smm rar->filename_allocated = newsize; 1426231200Smm } 1427231200Smm filename = rar->filename; 1428231200Smm memcpy(filename, p, filename_size); 1429231200Smm filename[filename_size] = '\0'; 1430231200Smm if (rar->file_flags & FHD_UNICODE) 1431231200Smm { 1432231200Smm if (filename_size != strlen(filename)) 1433231200Smm { 1434248616Smm unsigned char highbyte, flagbits, flagbyte; 1435248616Smm unsigned fn_end, offset; 1436231200Smm 1437231200Smm end = filename_size; 1438238856Smm fn_end = filename_size * 2; 1439231200Smm filename_size = 0; 1440248616Smm offset = (unsigned)strlen(filename) + 1; 1441231200Smm highbyte = *(p + offset++); 1442231200Smm flagbits = 0; 1443231200Smm flagbyte = 0; 1444238856Smm while (offset < end && filename_size < fn_end) 1445231200Smm { 1446231200Smm if (!flagbits) 1447231200Smm { 1448231200Smm flagbyte = *(p + offset++); 1449231200Smm flagbits = 8; 1450231200Smm } 1451299529Smm 1452231200Smm flagbits -= 2; 1453231200Smm switch((flagbyte >> flagbits) & 3) 1454231200Smm { 1455231200Smm case 0: 1456231200Smm filename[filename_size++] = '\0'; 1457231200Smm filename[filename_size++] = *(p + offset++); 1458231200Smm break; 1459231200Smm case 1: 1460231200Smm filename[filename_size++] = highbyte; 1461231200Smm filename[filename_size++] = *(p + offset++); 1462231200Smm break; 1463231200Smm case 2: 1464231200Smm filename[filename_size++] = *(p + offset + 1); 1465231200Smm filename[filename_size++] = *(p + offset); 1466231200Smm offset += 2; 1467231200Smm break; 1468231200Smm case 3: 1469231200Smm { 1470238856Smm char extra, high; 1471238856Smm uint8_t length = *(p + offset++); 1472238856Smm 1473238856Smm if (length & 0x80) { 1474238856Smm extra = *(p + offset++); 1475238856Smm high = (char)highbyte; 1476238856Smm } else 1477238856Smm extra = high = 0; 1478238856Smm length = (length & 0x7f) + 2; 1479238856Smm while (length && filename_size < fn_end) { 1480238856Smm unsigned cp = filename_size >> 1; 1481238856Smm filename[filename_size++] = high; 1482238856Smm filename[filename_size++] = p[cp] + extra; 1483231200Smm length--; 1484231200Smm } 1485231200Smm } 1486231200Smm break; 1487231200Smm } 1488231200Smm } 1489238856Smm if (filename_size > fn_end) { 1490231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1491231200Smm "Invalid filename"); 1492231200Smm return (ARCHIVE_FATAL); 1493231200Smm } 1494231200Smm filename[filename_size++] = '\0'; 1495324417Smm /* 1496324417Smm * Do not increment filename_size here as the computations below 1497324417Smm * add the space for the terminating NUL explicitly. 1498324417Smm */ 1499324417Smm filename[filename_size] = '\0'; 1500231200Smm 1501231200Smm /* Decoded unicode form is UTF-16BE, so we have to update a string 1502231200Smm * conversion object for it. */ 1503231200Smm if (rar->sconv_utf16be == NULL) { 1504231200Smm rar->sconv_utf16be = archive_string_conversion_from_charset( 1505231200Smm &a->archive, "UTF-16BE", 1); 1506231200Smm if (rar->sconv_utf16be == NULL) 1507231200Smm return (ARCHIVE_FATAL); 1508231200Smm } 1509231200Smm fn_sconv = rar->sconv_utf16be; 1510231200Smm 1511231200Smm strp = filename; 1512231200Smm while (memcmp(strp, "\x00\x00", 2)) 1513231200Smm { 1514231200Smm if (!memcmp(strp, "\x00\\", 2)) 1515231200Smm *(strp + 1) = '/'; 1516231200Smm strp += 2; 1517231200Smm } 1518231200Smm p += offset; 1519231200Smm } else { 1520231200Smm /* 1521231200Smm * If FHD_UNICODE is set but no unicode data, this file name form 1522231200Smm * is UTF-8, so we have to update a string conversion object for 1523231200Smm * it accordingly. 1524231200Smm */ 1525231200Smm if (rar->sconv_utf8 == NULL) { 1526231200Smm rar->sconv_utf8 = archive_string_conversion_from_charset( 1527231200Smm &a->archive, "UTF-8", 1); 1528231200Smm if (rar->sconv_utf8 == NULL) 1529231200Smm return (ARCHIVE_FATAL); 1530231200Smm } 1531231200Smm fn_sconv = rar->sconv_utf8; 1532231200Smm while ((strp = strchr(filename, '\\')) != NULL) 1533231200Smm *strp = '/'; 1534231200Smm p += filename_size; 1535231200Smm } 1536231200Smm } 1537231200Smm else 1538231200Smm { 1539231200Smm fn_sconv = sconv; 1540231200Smm while ((strp = strchr(filename, '\\')) != NULL) 1541231200Smm *strp = '/'; 1542231200Smm p += filename_size; 1543231200Smm } 1544231200Smm 1545248616Smm /* Split file in multivolume RAR. No more need to process header. */ 1546248616Smm if (rar->filename_save && 1547299529Smm filename_size == rar->filename_save_size && 1548248616Smm !memcmp(rar->filename, rar->filename_save, filename_size + 1)) 1549248616Smm { 1550248616Smm __archive_read_consume(a, header_size - 7); 1551248616Smm rar->cursor++; 1552248616Smm if (rar->cursor >= rar->nodes) 1553248616Smm { 1554248616Smm rar->nodes++; 1555248616Smm if ((rar->dbo = 1556248616Smm realloc(rar->dbo, sizeof(*rar->dbo) * rar->nodes)) == NULL) 1557248616Smm { 1558248616Smm archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory."); 1559248616Smm return (ARCHIVE_FATAL); 1560248616Smm } 1561248616Smm rar->dbo[rar->cursor].header_size = header_size; 1562248616Smm rar->dbo[rar->cursor].start_offset = -1; 1563248616Smm rar->dbo[rar->cursor].end_offset = -1; 1564248616Smm } 1565248616Smm if (rar->dbo[rar->cursor].start_offset < 0) 1566248616Smm { 1567248616Smm rar->dbo[rar->cursor].start_offset = a->filter->position; 1568248616Smm rar->dbo[rar->cursor].end_offset = rar->dbo[rar->cursor].start_offset + 1569248616Smm rar->packed_size; 1570248616Smm } 1571248616Smm return ret; 1572248616Smm } 1573342360Smm else if (rar->filename_must_match) 1574342360Smm { 1575342360Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1576342360Smm "Mismatch of file parts split across multi-volume archive"); 1577342360Smm return (ARCHIVE_FATAL); 1578342360Smm } 1579248616Smm 1580248616Smm rar->filename_save = (char*)realloc(rar->filename_save, 1581248616Smm filename_size + 1); 1582248616Smm memcpy(rar->filename_save, rar->filename, filename_size + 1); 1583299529Smm rar->filename_save_size = filename_size; 1584248616Smm 1585248616Smm /* Set info for seeking */ 1586248616Smm free(rar->dbo); 1587248616Smm if ((rar->dbo = calloc(1, sizeof(*rar->dbo))) == NULL) 1588248616Smm { 1589248616Smm archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory."); 1590248616Smm return (ARCHIVE_FATAL); 1591248616Smm } 1592248616Smm rar->dbo[0].header_size = header_size; 1593248616Smm rar->dbo[0].start_offset = -1; 1594248616Smm rar->dbo[0].end_offset = -1; 1595248616Smm rar->cursor = 0; 1596248616Smm rar->nodes = 1; 1597248616Smm 1598231200Smm if (rar->file_flags & FHD_SALT) 1599231200Smm { 1600231200Smm if (p + 8 > endp) { 1601231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1602231200Smm "Invalid header size"); 1603231200Smm return (ARCHIVE_FATAL); 1604231200Smm } 1605231200Smm memcpy(rar->salt, p, 8); 1606231200Smm p += 8; 1607231200Smm } 1608231200Smm 1609231200Smm if (rar->file_flags & FHD_EXTTIME) { 1610231200Smm if (read_exttime(p, rar, endp) < 0) { 1611231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1612231200Smm "Invalid header size"); 1613231200Smm return (ARCHIVE_FATAL); 1614231200Smm } 1615231200Smm } 1616231200Smm 1617231200Smm __archive_read_consume(a, header_size - 7); 1618248616Smm rar->dbo[0].start_offset = a->filter->position; 1619248616Smm rar->dbo[0].end_offset = rar->dbo[0].start_offset + rar->packed_size; 1620231200Smm 1621231200Smm switch(file_header.host_os) 1622231200Smm { 1623231200Smm case OS_MSDOS: 1624231200Smm case OS_OS2: 1625231200Smm case OS_WIN32: 1626231200Smm rar->mode = archive_le32dec(file_header.file_attr); 1627231200Smm if (rar->mode & FILE_ATTRIBUTE_DIRECTORY) 1628231200Smm rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; 1629231200Smm else 1630231200Smm rar->mode = AE_IFREG; 1631231200Smm rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 1632231200Smm break; 1633231200Smm 1634231200Smm case OS_UNIX: 1635231200Smm case OS_MAC_OS: 1636231200Smm case OS_BEOS: 1637231200Smm rar->mode = archive_le32dec(file_header.file_attr); 1638231200Smm break; 1639231200Smm 1640231200Smm default: 1641231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1642231200Smm "Unknown file attributes from RAR file's host OS"); 1643231200Smm return (ARCHIVE_FATAL); 1644231200Smm } 1645231200Smm 1646231200Smm rar->bytes_uncopied = rar->bytes_unconsumed = 0; 1647238856Smm rar->lzss.position = rar->offset = 0; 1648248616Smm rar->offset_seek = 0; 1649238856Smm rar->dictionary_size = 0; 1650231200Smm rar->offset_outgoing = 0; 1651231200Smm rar->br.cache_avail = 0; 1652231200Smm rar->br.avail_in = 0; 1653231200Smm rar->crc_calculated = 0; 1654231200Smm rar->entry_eof = 0; 1655231200Smm rar->valid = 1; 1656231200Smm rar->is_ppmd_block = 0; 1657231200Smm rar->start_new_table = 1; 1658231200Smm free(rar->unp_buffer); 1659231200Smm rar->unp_buffer = NULL; 1660231200Smm rar->unp_offset = 0; 1661231200Smm rar->unp_buffer_size = UNP_BUFFER_SIZE; 1662231200Smm memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); 1663328827Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); 1664231200Smm rar->ppmd_valid = rar->ppmd_eod = 0; 1665231200Smm 1666231200Smm /* Don't set any archive entries for non-file header types */ 1667231200Smm if (head_type == NEWSUB_HEAD) 1668231200Smm return ret; 1669231200Smm 1670231200Smm archive_entry_set_mtime(entry, rar->mtime, rar->mnsec); 1671231200Smm archive_entry_set_ctime(entry, rar->ctime, rar->cnsec); 1672231200Smm archive_entry_set_atime(entry, rar->atime, rar->ansec); 1673231200Smm archive_entry_set_size(entry, rar->unp_size); 1674231200Smm archive_entry_set_mode(entry, rar->mode); 1675231200Smm 1676231200Smm if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv)) 1677231200Smm { 1678231200Smm if (errno == ENOMEM) 1679231200Smm { 1680231200Smm archive_set_error(&a->archive, ENOMEM, 1681231200Smm "Can't allocate memory for Pathname"); 1682231200Smm return (ARCHIVE_FATAL); 1683231200Smm } 1684231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1685231200Smm "Pathname cannot be converted from %s to current locale.", 1686231200Smm archive_string_conversion_charset_name(fn_sconv)); 1687231200Smm ret = (ARCHIVE_WARN); 1688231200Smm } 1689231200Smm 1690231200Smm if (((rar->mode) & AE_IFMT) == AE_IFLNK) 1691231200Smm { 1692231200Smm /* Make sure a symbolic-link file does not have its body. */ 1693231200Smm rar->bytes_remaining = 0; 1694231200Smm archive_entry_set_size(entry, 0); 1695231200Smm 1696231200Smm /* Read a symbolic-link name. */ 1697231200Smm if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN)) 1698231200Smm return ret2; 1699231200Smm if (ret > ret2) 1700231200Smm ret = ret2; 1701231200Smm } 1702231200Smm 1703231200Smm if (rar->bytes_remaining == 0) 1704231200Smm rar->entry_eof = 1; 1705231200Smm 1706231200Smm return ret; 1707231200Smm} 1708231200Smm 1709231200Smmstatic time_t 1710232153Smmget_time(int ttime) 1711231200Smm{ 1712231200Smm struct tm tm; 1713232153Smm tm.tm_sec = 2 * (ttime & 0x1f); 1714232153Smm tm.tm_min = (ttime >> 5) & 0x3f; 1715232153Smm tm.tm_hour = (ttime >> 11) & 0x1f; 1716232153Smm tm.tm_mday = (ttime >> 16) & 0x1f; 1717232153Smm tm.tm_mon = ((ttime >> 21) & 0x0f) - 1; 1718232153Smm tm.tm_year = ((ttime >> 25) & 0x7f) + 80; 1719231200Smm tm.tm_isdst = -1; 1720231200Smm return mktime(&tm); 1721231200Smm} 1722231200Smm 1723231200Smmstatic int 1724231200Smmread_exttime(const char *p, struct rar *rar, const char *endp) 1725231200Smm{ 1726231200Smm unsigned rmode, flags, rem, j, count; 1727232153Smm int ttime, i; 1728231200Smm struct tm *tm; 1729231200Smm time_t t; 1730231200Smm long nsec; 1731358088Smm#if defined(HAVE_LOCALTIME_R) || defined(HAVE__LOCALTIME64_S) 1732358088Smm struct tm tmbuf; 1733358088Smm#endif 1734358088Smm#if defined(HAVE__LOCALTIME64_S) 1735358088Smm errno_t terr; 1736358088Smm __time64_t tmptime; 1737358088Smm#endif 1738231200Smm 1739231200Smm if (p + 2 > endp) 1740231200Smm return (-1); 1741231200Smm flags = archive_le16dec(p); 1742231200Smm p += 2; 1743231200Smm 1744231200Smm for (i = 3; i >= 0; i--) 1745231200Smm { 1746231200Smm t = 0; 1747231200Smm if (i == 3) 1748231200Smm t = rar->mtime; 1749231200Smm rmode = flags >> i * 4; 1750231200Smm if (rmode & 8) 1751231200Smm { 1752231200Smm if (!t) 1753231200Smm { 1754231200Smm if (p + 4 > endp) 1755231200Smm return (-1); 1756232153Smm ttime = archive_le32dec(p); 1757232153Smm t = get_time(ttime); 1758231200Smm p += 4; 1759231200Smm } 1760231200Smm rem = 0; 1761231200Smm count = rmode & 3; 1762231200Smm if (p + count > endp) 1763231200Smm return (-1); 1764231200Smm for (j = 0; j < count; j++) 1765231200Smm { 1766318482Smm rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8); 1767231200Smm p++; 1768231200Smm } 1769358088Smm#if defined(HAVE_LOCALTIME_R) 1770358088Smm tm = localtime_r(&t, &tmbuf); 1771358088Smm#elif defined(HAVE__LOCALTIME64_S) 1772358088Smm tmptime = t; 1773358088Smm terr = _localtime64_s(&tmbuf, &tmptime); 1774358088Smm if (terr) 1775358088Smm tm = NULL; 1776358088Smm else 1777358088Smm tm = &tmbuf; 1778358088Smm#else 1779231200Smm tm = localtime(&t); 1780358088Smm#endif 1781231200Smm nsec = tm->tm_sec + rem / NS_UNIT; 1782231200Smm if (rmode & 4) 1783231200Smm { 1784231200Smm tm->tm_sec++; 1785231200Smm t = mktime(tm); 1786231200Smm } 1787231200Smm if (i == 3) 1788231200Smm { 1789231200Smm rar->mtime = t; 1790231200Smm rar->mnsec = nsec; 1791231200Smm } 1792231200Smm else if (i == 2) 1793231200Smm { 1794231200Smm rar->ctime = t; 1795231200Smm rar->cnsec = nsec; 1796231200Smm } 1797231200Smm else if (i == 1) 1798231200Smm { 1799231200Smm rar->atime = t; 1800231200Smm rar->ansec = nsec; 1801231200Smm } 1802231200Smm else 1803231200Smm { 1804231200Smm rar->arctime = t; 1805231200Smm rar->arcnsec = nsec; 1806231200Smm } 1807231200Smm } 1808231200Smm } 1809231200Smm return (0); 1810231200Smm} 1811231200Smm 1812231200Smmstatic int 1813231200Smmread_symlink_stored(struct archive_read *a, struct archive_entry *entry, 1814231200Smm struct archive_string_conv *sconv) 1815231200Smm{ 1816231200Smm const void *h; 1817231200Smm const char *p; 1818231200Smm struct rar *rar; 1819231200Smm int ret = (ARCHIVE_OK); 1820231200Smm 1821231200Smm rar = (struct rar *)(a->format->data); 1822248616Smm if ((h = rar_read_ahead(a, (size_t)rar->packed_size, NULL)) == NULL) 1823231200Smm return (ARCHIVE_FATAL); 1824231200Smm p = h; 1825231200Smm 1826238856Smm if (archive_entry_copy_symlink_l(entry, 1827238856Smm p, (size_t)rar->packed_size, sconv)) 1828231200Smm { 1829231200Smm if (errno == ENOMEM) 1830231200Smm { 1831231200Smm archive_set_error(&a->archive, ENOMEM, 1832231200Smm "Can't allocate memory for link"); 1833231200Smm return (ARCHIVE_FATAL); 1834231200Smm } 1835231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1836231200Smm "link cannot be converted from %s to current locale.", 1837231200Smm archive_string_conversion_charset_name(sconv)); 1838231200Smm ret = (ARCHIVE_WARN); 1839231200Smm } 1840231200Smm __archive_read_consume(a, rar->packed_size); 1841231200Smm return ret; 1842231200Smm} 1843231200Smm 1844231200Smmstatic int 1845231200Smmread_data_stored(struct archive_read *a, const void **buff, size_t *size, 1846231200Smm int64_t *offset) 1847231200Smm{ 1848231200Smm struct rar *rar; 1849231200Smm ssize_t bytes_avail; 1850231200Smm 1851231200Smm rar = (struct rar *)(a->format->data); 1852248616Smm if (rar->bytes_remaining == 0 && 1853248616Smm !(rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER)) 1854231200Smm { 1855231200Smm *buff = NULL; 1856231200Smm *size = 0; 1857231200Smm *offset = rar->offset; 1858231200Smm if (rar->file_crc != rar->crc_calculated) { 1859231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1860231200Smm "File CRC error"); 1861231200Smm return (ARCHIVE_FATAL); 1862231200Smm } 1863231200Smm rar->entry_eof = 1; 1864231200Smm return (ARCHIVE_EOF); 1865231200Smm } 1866231200Smm 1867248616Smm *buff = rar_read_ahead(a, 1, &bytes_avail); 1868231200Smm if (bytes_avail <= 0) 1869231200Smm { 1870231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1871231200Smm "Truncated RAR file data"); 1872231200Smm return (ARCHIVE_FATAL); 1873231200Smm } 1874231200Smm 1875231200Smm *size = bytes_avail; 1876231200Smm *offset = rar->offset; 1877231200Smm rar->offset += bytes_avail; 1878248616Smm rar->offset_seek += bytes_avail; 1879231200Smm rar->bytes_remaining -= bytes_avail; 1880231200Smm rar->bytes_unconsumed = bytes_avail; 1881231200Smm /* Calculate File CRC. */ 1882248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, 1883248616Smm (unsigned)bytes_avail); 1884231200Smm return (ARCHIVE_OK); 1885231200Smm} 1886231200Smm 1887231200Smmstatic int 1888231200Smmread_data_compressed(struct archive_read *a, const void **buff, size_t *size, 1889368707Smm int64_t *offset, size_t looper) 1890231200Smm{ 1891368707Smm if (looper++ > MAX_COMPRESS_DEPTH) 1892368707Smm return (ARCHIVE_FATAL); 1893368707Smm 1894231200Smm struct rar *rar; 1895231200Smm int64_t start, end, actualend; 1896231200Smm size_t bs; 1897231200Smm int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i; 1898231200Smm 1899231200Smm rar = (struct rar *)(a->format->data); 1900231200Smm 1901231200Smm do { 1902231200Smm if (!rar->valid) 1903231200Smm return (ARCHIVE_FATAL); 1904231200Smm if (rar->ppmd_eod || 1905231200Smm (rar->dictionary_size && rar->offset >= rar->unp_size)) 1906231200Smm { 1907231200Smm if (rar->unp_offset > 0) { 1908231200Smm /* 1909231200Smm * We have unprocessed extracted data. write it out. 1910231200Smm */ 1911231200Smm *buff = rar->unp_buffer; 1912231200Smm *size = rar->unp_offset; 1913231200Smm *offset = rar->offset_outgoing; 1914231200Smm rar->offset_outgoing += *size; 1915231200Smm /* Calculate File CRC. */ 1916248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, 1917248616Smm (unsigned)*size); 1918231200Smm rar->unp_offset = 0; 1919231200Smm return (ARCHIVE_OK); 1920231200Smm } 1921231200Smm *buff = NULL; 1922231200Smm *size = 0; 1923231200Smm *offset = rar->offset; 1924231200Smm if (rar->file_crc != rar->crc_calculated) { 1925231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1926231200Smm "File CRC error"); 1927231200Smm return (ARCHIVE_FATAL); 1928231200Smm } 1929231200Smm rar->entry_eof = 1; 1930231200Smm return (ARCHIVE_EOF); 1931231200Smm } 1932231200Smm 1933231200Smm if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0) 1934231200Smm { 1935231200Smm if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) 1936231200Smm bs = rar->unp_buffer_size - rar->unp_offset; 1937231200Smm else 1938238856Smm bs = (size_t)rar->bytes_uncopied; 1939248616Smm ret = copy_from_lzss_window(a, buff, rar->offset, (int)bs); 1940231200Smm if (ret != ARCHIVE_OK) 1941231200Smm return (ret); 1942231200Smm rar->offset += bs; 1943231200Smm rar->bytes_uncopied -= bs; 1944231200Smm if (*buff != NULL) { 1945231200Smm rar->unp_offset = 0; 1946231200Smm *size = rar->unp_buffer_size; 1947231200Smm *offset = rar->offset_outgoing; 1948231200Smm rar->offset_outgoing += *size; 1949231200Smm /* Calculate File CRC. */ 1950248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, 1951248616Smm (unsigned)*size); 1952231200Smm return (ret); 1953231200Smm } 1954231200Smm continue; 1955231200Smm } 1956231200Smm 1957231200Smm if (!rar->br.next_in && 1958231200Smm (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN) 1959231200Smm return (ret); 1960231200Smm if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN))) 1961231200Smm return (ret); 1962231200Smm 1963231200Smm if (rar->is_ppmd_block) 1964231200Smm { 1965231200Smm if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1966231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1967231200Smm { 1968231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1969231200Smm "Invalid symbol"); 1970231200Smm return (ARCHIVE_FATAL); 1971231200Smm } 1972231200Smm if(sym != rar->ppmd_escape) 1973231200Smm { 1974231200Smm lzss_emit_literal(rar, sym); 1975231200Smm rar->bytes_uncopied++; 1976231200Smm } 1977231200Smm else 1978231200Smm { 1979231200Smm if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 1980231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 1981231200Smm { 1982231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 1983231200Smm "Invalid symbol"); 1984231200Smm return (ARCHIVE_FATAL); 1985231200Smm } 1986231200Smm 1987231200Smm switch(code) 1988231200Smm { 1989231200Smm case 0: 1990231200Smm rar->start_new_table = 1; 1991368707Smm return read_data_compressed(a, buff, size, offset, looper); 1992231200Smm 1993231200Smm case 2: 1994231200Smm rar->ppmd_eod = 1;/* End Of ppmd Data. */ 1995231200Smm continue; 1996231200Smm 1997231200Smm case 3: 1998231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1999231200Smm "Parsing filters is unsupported."); 2000231200Smm return (ARCHIVE_FAILED); 2001231200Smm 2002231200Smm case 4: 2003231200Smm lzss_offset = 0; 2004231200Smm for (i = 2; i >= 0; i--) 2005231200Smm { 2006231200Smm if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 2007231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 2008231200Smm { 2009231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2010231200Smm "Invalid symbol"); 2011231200Smm return (ARCHIVE_FATAL); 2012231200Smm } 2013231200Smm lzss_offset |= code << (i * 8); 2014231200Smm } 2015231200Smm if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 2016231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 2017231200Smm { 2018231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2019231200Smm "Invalid symbol"); 2020231200Smm return (ARCHIVE_FATAL); 2021231200Smm } 2022231200Smm lzss_emit_match(rar, lzss_offset + 2, length + 32); 2023231200Smm rar->bytes_uncopied += length + 32; 2024231200Smm break; 2025231200Smm 2026231200Smm case 5: 2027231200Smm if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( 2028231200Smm &rar->ppmd7_context, &rar->range_dec.p)) < 0) 2029231200Smm { 2030231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2031231200Smm "Invalid symbol"); 2032231200Smm return (ARCHIVE_FATAL); 2033231200Smm } 2034231200Smm lzss_emit_match(rar, 1, length + 4); 2035231200Smm rar->bytes_uncopied += length + 4; 2036231200Smm break; 2037231200Smm 2038231200Smm default: 2039231200Smm lzss_emit_literal(rar, sym); 2040231200Smm rar->bytes_uncopied++; 2041231200Smm } 2042231200Smm } 2043231200Smm } 2044231200Smm else 2045231200Smm { 2046231200Smm start = rar->offset; 2047231200Smm end = start + rar->dictionary_size; 2048231200Smm rar->filterstart = INT64_MAX; 2049231200Smm 2050231200Smm if ((actualend = expand(a, end)) < 0) 2051231200Smm return ((int)actualend); 2052231200Smm 2053231200Smm rar->bytes_uncopied = actualend - start; 2054231200Smm if (rar->bytes_uncopied == 0) { 2055231200Smm /* Broken RAR files cause this case. 2056231200Smm * NOTE: If this case were possible on a normal RAR file 2057231200Smm * we would find out where it was actually bad and 2058231200Smm * what we would do to solve it. */ 2059231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2060231200Smm "Internal error extracting RAR file"); 2061231200Smm return (ARCHIVE_FATAL); 2062231200Smm } 2063231200Smm } 2064231200Smm if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) 2065231200Smm bs = rar->unp_buffer_size - rar->unp_offset; 2066231200Smm else 2067238856Smm bs = (size_t)rar->bytes_uncopied; 2068248616Smm ret = copy_from_lzss_window(a, buff, rar->offset, (int)bs); 2069231200Smm if (ret != ARCHIVE_OK) 2070231200Smm return (ret); 2071231200Smm rar->offset += bs; 2072231200Smm rar->bytes_uncopied -= bs; 2073231200Smm /* 2074231200Smm * If *buff is NULL, it means unp_buffer is not full. 2075231200Smm * So we have to continue extracting a RAR file. 2076231200Smm */ 2077231200Smm } while (*buff == NULL); 2078231200Smm 2079231200Smm rar->unp_offset = 0; 2080231200Smm *size = rar->unp_buffer_size; 2081231200Smm *offset = rar->offset_outgoing; 2082231200Smm rar->offset_outgoing += *size; 2083231200Smm /* Calculate File CRC. */ 2084248616Smm rar->crc_calculated = crc32(rar->crc_calculated, *buff, (unsigned)*size); 2085231200Smm return ret; 2086231200Smm} 2087231200Smm 2088231200Smmstatic int 2089231200Smmparse_codes(struct archive_read *a) 2090231200Smm{ 2091231200Smm int i, j, val, n, r; 2092231200Smm unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags; 2093231200Smm unsigned int maxorder; 2094231200Smm struct huffman_code precode; 2095231200Smm struct rar *rar = (struct rar *)(a->format->data); 2096231200Smm struct rar_br *br = &(rar->br); 2097231200Smm 2098231200Smm free_codes(a); 2099231200Smm 2100231200Smm /* Skip to the next byte */ 2101231200Smm rar_br_consume_unalined_bits(br); 2102231200Smm 2103231200Smm /* PPMd block flag */ 2104231200Smm if (!rar_br_read_ahead(a, br, 1)) 2105231200Smm goto truncated_data; 2106231200Smm if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0) 2107231200Smm { 2108231200Smm rar_br_consume(br, 1); 2109231200Smm if (!rar_br_read_ahead(a, br, 7)) 2110231200Smm goto truncated_data; 2111231200Smm ppmd_flags = rar_br_bits(br, 7); 2112231200Smm rar_br_consume(br, 7); 2113231200Smm 2114231200Smm /* Memory is allocated in MB */ 2115231200Smm if (ppmd_flags & 0x20) 2116231200Smm { 2117231200Smm if (!rar_br_read_ahead(a, br, 8)) 2118231200Smm goto truncated_data; 2119231200Smm rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20; 2120231200Smm rar_br_consume(br, 8); 2121231200Smm } 2122231200Smm 2123231200Smm if (ppmd_flags & 0x40) 2124231200Smm { 2125231200Smm if (!rar_br_read_ahead(a, br, 8)) 2126231200Smm goto truncated_data; 2127231200Smm rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8); 2128231200Smm rar_br_consume(br, 8); 2129231200Smm } 2130231200Smm else 2131231200Smm rar->ppmd_escape = 2; 2132231200Smm 2133231200Smm if (ppmd_flags & 0x20) 2134231200Smm { 2135231200Smm maxorder = (ppmd_flags & 0x1F) + 1; 2136231200Smm if(maxorder > 16) 2137231200Smm maxorder = 16 + (maxorder - 16) * 3; 2138231200Smm 2139231200Smm if (maxorder == 1) 2140231200Smm { 2141231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2142231200Smm "Truncated RAR file data"); 2143231200Smm return (ARCHIVE_FATAL); 2144231200Smm } 2145231200Smm 2146231200Smm /* Make sure ppmd7_contest is freed before Ppmd7_Construct 2147231200Smm * because reading a broken file cause this abnormal sequence. */ 2148328827Smm __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); 2149231200Smm 2150231200Smm rar->bytein.a = a; 2151231200Smm rar->bytein.Read = &ppmd_read; 2152231200Smm __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec); 2153231200Smm rar->range_dec.Stream = &rar->bytein; 2154231200Smm __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context); 2155231200Smm 2156302075Smm if (rar->dictionary_size == 0) { 2157302075Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2158302075Smm "Invalid zero dictionary size"); 2159302075Smm return (ARCHIVE_FATAL); 2160302075Smm } 2161302075Smm 2162231200Smm if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context, 2163328827Smm rar->dictionary_size)) 2164231200Smm { 2165231200Smm archive_set_error(&a->archive, ENOMEM, 2166231200Smm "Out of memory"); 2167231200Smm return (ARCHIVE_FATAL); 2168231200Smm } 2169231200Smm if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) 2170231200Smm { 2171231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2172231200Smm "Unable to initialize PPMd range decoder"); 2173231200Smm return (ARCHIVE_FATAL); 2174231200Smm } 2175231200Smm __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder); 2176231200Smm rar->ppmd_valid = 1; 2177231200Smm } 2178231200Smm else 2179231200Smm { 2180231200Smm if (!rar->ppmd_valid) { 2181231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2182231200Smm "Invalid PPMd sequence"); 2183231200Smm return (ARCHIVE_FATAL); 2184231200Smm } 2185231200Smm if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) 2186231200Smm { 2187231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2188231200Smm "Unable to initialize PPMd range decoder"); 2189231200Smm return (ARCHIVE_FATAL); 2190231200Smm } 2191231200Smm } 2192231200Smm } 2193231200Smm else 2194231200Smm { 2195231200Smm rar_br_consume(br, 1); 2196231200Smm 2197231200Smm /* Keep existing table flag */ 2198231200Smm if (!rar_br_read_ahead(a, br, 1)) 2199231200Smm goto truncated_data; 2200231200Smm if (!rar_br_bits(br, 1)) 2201231200Smm memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); 2202231200Smm rar_br_consume(br, 1); 2203231200Smm 2204231200Smm memset(&bitlengths, 0, sizeof(bitlengths)); 2205231200Smm for (i = 0; i < MAX_SYMBOLS;) 2206231200Smm { 2207231200Smm if (!rar_br_read_ahead(a, br, 4)) 2208231200Smm goto truncated_data; 2209231200Smm bitlengths[i++] = rar_br_bits(br, 4); 2210231200Smm rar_br_consume(br, 4); 2211231200Smm if (bitlengths[i-1] == 0xF) 2212231200Smm { 2213231200Smm if (!rar_br_read_ahead(a, br, 4)) 2214231200Smm goto truncated_data; 2215231200Smm zerocount = rar_br_bits(br, 4); 2216231200Smm rar_br_consume(br, 4); 2217231200Smm if (zerocount) 2218231200Smm { 2219231200Smm i--; 2220231200Smm for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++) 2221231200Smm bitlengths[i++] = 0; 2222231200Smm } 2223231200Smm } 2224231200Smm } 2225231200Smm 2226231200Smm memset(&precode, 0, sizeof(precode)); 2227231200Smm r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH); 2228231200Smm if (r != ARCHIVE_OK) { 2229231200Smm free(precode.tree); 2230231200Smm free(precode.table); 2231231200Smm return (r); 2232231200Smm } 2233231200Smm 2234231200Smm for (i = 0; i < HUFFMAN_TABLE_SIZE;) 2235231200Smm { 2236231200Smm if ((val = read_next_symbol(a, &precode)) < 0) { 2237231200Smm free(precode.tree); 2238231200Smm free(precode.table); 2239231200Smm return (ARCHIVE_FATAL); 2240231200Smm } 2241231200Smm if (val < 16) 2242231200Smm { 2243231200Smm rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF; 2244231200Smm i++; 2245231200Smm } 2246231200Smm else if (val < 18) 2247231200Smm { 2248231200Smm if (i == 0) 2249231200Smm { 2250231200Smm free(precode.tree); 2251231200Smm free(precode.table); 2252231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2253231200Smm "Internal error extracting RAR file."); 2254231200Smm return (ARCHIVE_FATAL); 2255231200Smm } 2256231200Smm 2257231200Smm if(val == 16) { 2258231200Smm if (!rar_br_read_ahead(a, br, 3)) { 2259231200Smm free(precode.tree); 2260231200Smm free(precode.table); 2261231200Smm goto truncated_data; 2262231200Smm } 2263231200Smm n = rar_br_bits(br, 3) + 3; 2264231200Smm rar_br_consume(br, 3); 2265231200Smm } else { 2266231200Smm if (!rar_br_read_ahead(a, br, 7)) { 2267231200Smm free(precode.tree); 2268231200Smm free(precode.table); 2269231200Smm goto truncated_data; 2270231200Smm } 2271231200Smm n = rar_br_bits(br, 7) + 11; 2272231200Smm rar_br_consume(br, 7); 2273231200Smm } 2274231200Smm 2275231200Smm for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) 2276231200Smm { 2277231200Smm rar->lengthtable[i] = rar->lengthtable[i-1]; 2278231200Smm i++; 2279231200Smm } 2280231200Smm } 2281231200Smm else 2282231200Smm { 2283231200Smm if(val == 18) { 2284231200Smm if (!rar_br_read_ahead(a, br, 3)) { 2285231200Smm free(precode.tree); 2286231200Smm free(precode.table); 2287231200Smm goto truncated_data; 2288231200Smm } 2289231200Smm n = rar_br_bits(br, 3) + 3; 2290231200Smm rar_br_consume(br, 3); 2291231200Smm } else { 2292231200Smm if (!rar_br_read_ahead(a, br, 7)) { 2293231200Smm free(precode.tree); 2294231200Smm free(precode.table); 2295231200Smm goto truncated_data; 2296231200Smm } 2297231200Smm n = rar_br_bits(br, 7) + 11; 2298231200Smm rar_br_consume(br, 7); 2299231200Smm } 2300231200Smm 2301231200Smm for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) 2302231200Smm rar->lengthtable[i++] = 0; 2303231200Smm } 2304231200Smm } 2305231200Smm free(precode.tree); 2306231200Smm free(precode.table); 2307231200Smm 2308231200Smm r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE, 2309231200Smm MAX_SYMBOL_LENGTH); 2310231200Smm if (r != ARCHIVE_OK) 2311231200Smm return (r); 2312231200Smm r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE], 2313231200Smm OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); 2314231200Smm if (r != ARCHIVE_OK) 2315231200Smm return (r); 2316231200Smm r = create_code(a, &rar->lowoffsetcode, 2317231200Smm &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE], 2318231200Smm LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); 2319231200Smm if (r != ARCHIVE_OK) 2320231200Smm return (r); 2321231200Smm r = create_code(a, &rar->lengthcode, 2322231200Smm &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE + 2323231200Smm LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH); 2324231200Smm if (r != ARCHIVE_OK) 2325231200Smm return (r); 2326231200Smm } 2327231200Smm 2328231200Smm if (!rar->dictionary_size || !rar->lzss.window) 2329231200Smm { 2330231200Smm /* Seems as though dictionary sizes are not used. Even so, minimize 2331231200Smm * memory usage as much as possible. 2332231200Smm */ 2333248616Smm void *new_window; 2334248616Smm unsigned int new_size; 2335248616Smm 2336231200Smm if (rar->unp_size >= DICTIONARY_MAX_SIZE) 2337248616Smm new_size = DICTIONARY_MAX_SIZE; 2338231200Smm else 2339248616Smm new_size = rar_fls((unsigned int)rar->unp_size) << 1; 2340342360Smm if (new_size == 0) { 2341342360Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2342342360Smm "Zero window size is invalid."); 2343342360Smm return (ARCHIVE_FATAL); 2344342360Smm } 2345248616Smm new_window = realloc(rar->lzss.window, new_size); 2346248616Smm if (new_window == NULL) { 2347231200Smm archive_set_error(&a->archive, ENOMEM, 2348231200Smm "Unable to allocate memory for uncompressed data."); 2349231200Smm return (ARCHIVE_FATAL); 2350231200Smm } 2351248616Smm rar->lzss.window = (unsigned char *)new_window; 2352248616Smm rar->dictionary_size = new_size; 2353231200Smm memset(rar->lzss.window, 0, rar->dictionary_size); 2354231200Smm rar->lzss.mask = rar->dictionary_size - 1; 2355231200Smm } 2356231200Smm 2357231200Smm rar->start_new_table = 0; 2358231200Smm return (ARCHIVE_OK); 2359231200Smmtruncated_data: 2360231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2361231200Smm "Truncated RAR file data"); 2362231200Smm rar->valid = 0; 2363231200Smm return (ARCHIVE_FATAL); 2364231200Smm} 2365231200Smm 2366231200Smmstatic void 2367231200Smmfree_codes(struct archive_read *a) 2368231200Smm{ 2369231200Smm struct rar *rar = (struct rar *)(a->format->data); 2370231200Smm free(rar->maincode.tree); 2371231200Smm free(rar->offsetcode.tree); 2372231200Smm free(rar->lowoffsetcode.tree); 2373231200Smm free(rar->lengthcode.tree); 2374231200Smm free(rar->maincode.table); 2375231200Smm free(rar->offsetcode.table); 2376231200Smm free(rar->lowoffsetcode.table); 2377231200Smm free(rar->lengthcode.table); 2378231200Smm memset(&rar->maincode, 0, sizeof(rar->maincode)); 2379231200Smm memset(&rar->offsetcode, 0, sizeof(rar->offsetcode)); 2380231200Smm memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode)); 2381231200Smm memset(&rar->lengthcode, 0, sizeof(rar->lengthcode)); 2382231200Smm} 2383231200Smm 2384231200Smm 2385231200Smmstatic int 2386231200Smmread_next_symbol(struct archive_read *a, struct huffman_code *code) 2387231200Smm{ 2388231200Smm unsigned char bit; 2389231200Smm unsigned int bits; 2390231200Smm int length, value, node; 2391231200Smm struct rar *rar; 2392231200Smm struct rar_br *br; 2393231200Smm 2394231200Smm if (!code->table) 2395231200Smm { 2396231200Smm if (make_table(a, code) != (ARCHIVE_OK)) 2397231200Smm return -1; 2398231200Smm } 2399231200Smm 2400231200Smm rar = (struct rar *)(a->format->data); 2401231200Smm br = &(rar->br); 2402231200Smm 2403231200Smm /* Look ahead (peek) at bits */ 2404231200Smm if (!rar_br_read_ahead(a, br, code->tablesize)) { 2405231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2406231200Smm "Truncated RAR file data"); 2407231200Smm rar->valid = 0; 2408231200Smm return -1; 2409231200Smm } 2410231200Smm bits = rar_br_bits(br, code->tablesize); 2411231200Smm 2412231200Smm length = code->table[bits].length; 2413231200Smm value = code->table[bits].value; 2414231200Smm 2415231200Smm if (length < 0) 2416231200Smm { 2417231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2418231200Smm "Invalid prefix code in bitstream"); 2419231200Smm return -1; 2420231200Smm } 2421231200Smm 2422231200Smm if (length <= code->tablesize) 2423231200Smm { 2424231200Smm /* Skip length bits */ 2425231200Smm rar_br_consume(br, length); 2426231200Smm return value; 2427231200Smm } 2428231200Smm 2429231200Smm /* Skip tablesize bits */ 2430231200Smm rar_br_consume(br, code->tablesize); 2431231200Smm 2432231200Smm node = value; 2433231200Smm while (!(code->tree[node].branches[0] == 2434231200Smm code->tree[node].branches[1])) 2435231200Smm { 2436231200Smm if (!rar_br_read_ahead(a, br, 1)) { 2437231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2438231200Smm "Truncated RAR file data"); 2439231200Smm rar->valid = 0; 2440231200Smm return -1; 2441231200Smm } 2442231200Smm bit = rar_br_bits(br, 1); 2443231200Smm rar_br_consume(br, 1); 2444231200Smm 2445231200Smm if (code->tree[node].branches[bit] < 0) 2446231200Smm { 2447231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2448231200Smm "Invalid prefix code in bitstream"); 2449231200Smm return -1; 2450231200Smm } 2451231200Smm node = code->tree[node].branches[bit]; 2452231200Smm } 2453231200Smm 2454231200Smm return code->tree[node].branches[0]; 2455231200Smm} 2456231200Smm 2457231200Smmstatic int 2458231200Smmcreate_code(struct archive_read *a, struct huffman_code *code, 2459231200Smm unsigned char *lengths, int numsymbols, char maxlength) 2460231200Smm{ 2461231200Smm int i, j, codebits = 0, symbolsleft = numsymbols; 2462231200Smm 2463299529Smm code->numentries = 0; 2464299529Smm code->numallocatedentries = 0; 2465231200Smm if (new_node(code) < 0) { 2466231200Smm archive_set_error(&a->archive, ENOMEM, 2467231200Smm "Unable to allocate memory for node data."); 2468231200Smm return (ARCHIVE_FATAL); 2469231200Smm } 2470231200Smm code->numentries = 1; 2471231200Smm code->minlength = INT_MAX; 2472231200Smm code->maxlength = INT_MIN; 2473231200Smm codebits = 0; 2474231200Smm for(i = 1; i <= maxlength; i++) 2475231200Smm { 2476231200Smm for(j = 0; j < numsymbols; j++) 2477231200Smm { 2478231200Smm if (lengths[j] != i) continue; 2479231200Smm if (add_value(a, code, j, codebits, i) != ARCHIVE_OK) 2480231200Smm return (ARCHIVE_FATAL); 2481231200Smm codebits++; 2482358088Smm if (--symbolsleft <= 0) 2483358088Smm break; 2484231200Smm } 2485358088Smm if (symbolsleft <= 0) 2486358088Smm break; 2487231200Smm codebits <<= 1; 2488231200Smm } 2489231200Smm return (ARCHIVE_OK); 2490231200Smm} 2491231200Smm 2492231200Smmstatic int 2493231200Smmadd_value(struct archive_read *a, struct huffman_code *code, int value, 2494231200Smm int codebits, int length) 2495231200Smm{ 2496358088Smm int lastnode, bitpos, bit; 2497358088Smm /* int repeatpos, repeatnode, nextnode; */ 2498231200Smm 2499231200Smm free(code->table); 2500231200Smm code->table = NULL; 2501231200Smm 2502231200Smm if(length > code->maxlength) 2503231200Smm code->maxlength = length; 2504231200Smm if(length < code->minlength) 2505231200Smm code->minlength = length; 2506231200Smm 2507358088Smm /* 2508358088Smm * Dead code, repeatpos was is -1 2509358088Smm * 2510231200Smm repeatpos = -1; 2511231200Smm if (repeatpos == 0 || (repeatpos >= 0 2512231200Smm && (((codebits >> (repeatpos - 1)) & 3) == 0 2513231200Smm || ((codebits >> (repeatpos - 1)) & 3) == 3))) 2514231200Smm { 2515231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2516231200Smm "Invalid repeat position"); 2517231200Smm return (ARCHIVE_FATAL); 2518231200Smm } 2519358088Smm */ 2520231200Smm 2521231200Smm lastnode = 0; 2522231200Smm for (bitpos = length - 1; bitpos >= 0; bitpos--) 2523231200Smm { 2524231200Smm bit = (codebits >> bitpos) & 1; 2525231200Smm 2526231200Smm /* Leaf node check */ 2527231200Smm if (code->tree[lastnode].branches[0] == 2528231200Smm code->tree[lastnode].branches[1]) 2529231200Smm { 2530231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2531231200Smm "Prefix found"); 2532231200Smm return (ARCHIVE_FATAL); 2533231200Smm } 2534231200Smm 2535358088Smm /* 2536358088Smm * Dead code, repeatpos was -1, bitpos >=0 2537358088Smm * 2538231200Smm if (bitpos == repeatpos) 2539231200Smm { 2540358088Smm * Open branch check * 2541231200Smm if (!(code->tree[lastnode].branches[bit] < 0)) 2542231200Smm { 2543231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2544231200Smm "Invalid repeating code"); 2545231200Smm return (ARCHIVE_FATAL); 2546231200Smm } 2547231200Smm 2548231200Smm if ((repeatnode = new_node(code)) < 0) { 2549231200Smm archive_set_error(&a->archive, ENOMEM, 2550231200Smm "Unable to allocate memory for node data."); 2551231200Smm return (ARCHIVE_FATAL); 2552231200Smm } 2553231200Smm if ((nextnode = new_node(code)) < 0) { 2554231200Smm archive_set_error(&a->archive, ENOMEM, 2555231200Smm "Unable to allocate memory for node data."); 2556231200Smm return (ARCHIVE_FATAL); 2557231200Smm } 2558231200Smm 2559358088Smm * Set branches * 2560231200Smm code->tree[lastnode].branches[bit] = repeatnode; 2561231200Smm code->tree[repeatnode].branches[bit] = repeatnode; 2562231200Smm code->tree[repeatnode].branches[bit^1] = nextnode; 2563231200Smm lastnode = nextnode; 2564231200Smm 2565358088Smm bitpos++; * terminating bit already handled, skip it * 2566231200Smm } 2567231200Smm else 2568231200Smm { 2569358088Smm */ 2570231200Smm /* Open branch check */ 2571231200Smm if (code->tree[lastnode].branches[bit] < 0) 2572231200Smm { 2573231200Smm if (new_node(code) < 0) { 2574231200Smm archive_set_error(&a->archive, ENOMEM, 2575231200Smm "Unable to allocate memory for node data."); 2576231200Smm return (ARCHIVE_FATAL); 2577231200Smm } 2578231200Smm code->tree[lastnode].branches[bit] = code->numentries++; 2579231200Smm } 2580231200Smm 2581231200Smm /* set to branch */ 2582231200Smm lastnode = code->tree[lastnode].branches[bit]; 2583358088Smm /* } */ 2584231200Smm } 2585231200Smm 2586231200Smm if (!(code->tree[lastnode].branches[0] == -1 2587231200Smm && code->tree[lastnode].branches[1] == -2)) 2588231200Smm { 2589231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2590231200Smm "Prefix found"); 2591231200Smm return (ARCHIVE_FATAL); 2592231200Smm } 2593231200Smm 2594231200Smm /* Set leaf value */ 2595231200Smm code->tree[lastnode].branches[0] = value; 2596231200Smm code->tree[lastnode].branches[1] = value; 2597231200Smm 2598231200Smm return (ARCHIVE_OK); 2599231200Smm} 2600231200Smm 2601231200Smmstatic int 2602231200Smmnew_node(struct huffman_code *code) 2603231200Smm{ 2604248616Smm void *new_tree; 2605299529Smm if (code->numallocatedentries == code->numentries) { 2606299529Smm int new_num_entries = 256; 2607299529Smm if (code->numentries > 0) { 2608299529Smm new_num_entries = code->numentries * 2; 2609299529Smm } 2610299529Smm new_tree = realloc(code->tree, new_num_entries * sizeof(*code->tree)); 2611299529Smm if (new_tree == NULL) 2612299529Smm return (-1); 2613299529Smm code->tree = (struct huffman_tree_node *)new_tree; 2614299529Smm code->numallocatedentries = new_num_entries; 2615299529Smm } 2616231200Smm code->tree[code->numentries].branches[0] = -1; 2617231200Smm code->tree[code->numentries].branches[1] = -2; 2618231200Smm return 1; 2619231200Smm} 2620231200Smm 2621231200Smmstatic int 2622231200Smmmake_table(struct archive_read *a, struct huffman_code *code) 2623231200Smm{ 2624231200Smm if (code->maxlength < code->minlength || code->maxlength > 10) 2625231200Smm code->tablesize = 10; 2626231200Smm else 2627231200Smm code->tablesize = code->maxlength; 2628231200Smm 2629231200Smm code->table = 2630248616Smm (struct huffman_table_entry *)calloc(1, sizeof(*code->table) 2631248616Smm * ((size_t)1 << code->tablesize)); 2632231200Smm 2633231200Smm return make_table_recurse(a, code, 0, code->table, 0, code->tablesize); 2634231200Smm} 2635231200Smm 2636231200Smmstatic int 2637231200Smmmake_table_recurse(struct archive_read *a, struct huffman_code *code, int node, 2638231200Smm struct huffman_table_entry *table, int depth, 2639231200Smm int maxdepth) 2640231200Smm{ 2641231200Smm int currtablesize, i, ret = (ARCHIVE_OK); 2642231200Smm 2643231200Smm if (!code->tree) 2644231200Smm { 2645231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2646231200Smm "Huffman tree was not created."); 2647231200Smm return (ARCHIVE_FATAL); 2648231200Smm } 2649231200Smm if (node < 0 || node >= code->numentries) 2650231200Smm { 2651231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2652231200Smm "Invalid location to Huffman tree specified."); 2653231200Smm return (ARCHIVE_FATAL); 2654231200Smm } 2655231200Smm 2656231200Smm currtablesize = 1 << (maxdepth - depth); 2657231200Smm 2658231200Smm if (code->tree[node].branches[0] == 2659231200Smm code->tree[node].branches[1]) 2660231200Smm { 2661231200Smm for(i = 0; i < currtablesize; i++) 2662231200Smm { 2663231200Smm table[i].length = depth; 2664231200Smm table[i].value = code->tree[node].branches[0]; 2665231200Smm } 2666231200Smm } 2667358088Smm /* 2668358088Smm * Dead code, node >= 0 2669358088Smm * 2670231200Smm else if (node < 0) 2671231200Smm { 2672231200Smm for(i = 0; i < currtablesize; i++) 2673231200Smm table[i].length = -1; 2674231200Smm } 2675358088Smm */ 2676231200Smm else 2677231200Smm { 2678231200Smm if(depth == maxdepth) 2679231200Smm { 2680231200Smm table[0].length = maxdepth + 1; 2681231200Smm table[0].value = node; 2682231200Smm } 2683231200Smm else 2684231200Smm { 2685231200Smm ret |= make_table_recurse(a, code, code->tree[node].branches[0], table, 2686231200Smm depth + 1, maxdepth); 2687231200Smm ret |= make_table_recurse(a, code, code->tree[node].branches[1], 2688231200Smm table + currtablesize / 2, depth + 1, maxdepth); 2689231200Smm } 2690231200Smm } 2691231200Smm return ret; 2692231200Smm} 2693231200Smm 2694231200Smmstatic int64_t 2695231200Smmexpand(struct archive_read *a, int64_t end) 2696231200Smm{ 2697231200Smm static const unsigned char lengthbases[] = 2698231200Smm { 0, 1, 2, 3, 4, 5, 6, 2699231200Smm 7, 8, 10, 12, 14, 16, 20, 2700231200Smm 24, 28, 32, 40, 48, 56, 64, 2701231200Smm 80, 96, 112, 128, 160, 192, 224 }; 2702231200Smm static const unsigned char lengthbits[] = 2703231200Smm { 0, 0, 0, 0, 0, 0, 0, 2704231200Smm 0, 1, 1, 1, 1, 2, 2, 2705231200Smm 2, 2, 3, 3, 3, 3, 4, 2706231200Smm 4, 4, 4, 5, 5, 5, 5 }; 2707358088Smm static const int lengthb_min = minimum( 2708358088Smm (int)(sizeof(lengthbases)/sizeof(lengthbases[0])), 2709358088Smm (int)(sizeof(lengthbits)/sizeof(lengthbits[0])) 2710358088Smm ); 2711231200Smm static const unsigned int offsetbases[] = 2712231200Smm { 0, 1, 2, 3, 4, 6, 2713231200Smm 8, 12, 16, 24, 32, 48, 2714231200Smm 64, 96, 128, 192, 256, 384, 2715231200Smm 512, 768, 1024, 1536, 2048, 3072, 2716231200Smm 4096, 6144, 8192, 12288, 16384, 24576, 2717231200Smm 32768, 49152, 65536, 98304, 131072, 196608, 2718231200Smm 262144, 327680, 393216, 458752, 524288, 589824, 2719231200Smm 655360, 720896, 786432, 851968, 917504, 983040, 2720231200Smm 1048576, 1310720, 1572864, 1835008, 2097152, 2359296, 2721231200Smm 2621440, 2883584, 3145728, 3407872, 3670016, 3932160 }; 2722231200Smm static const unsigned char offsetbits[] = 2723231200Smm { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 2724231200Smm 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 2725231200Smm 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 2726231200Smm 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2727231200Smm 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; 2728358088Smm static const int offsetb_min = minimum( 2729358088Smm (int)(sizeof(offsetbases)/sizeof(offsetbases[0])), 2730358088Smm (int)(sizeof(offsetbits)/sizeof(offsetbits[0])) 2731358088Smm ); 2732231200Smm static const unsigned char shortbases[] = 2733231200Smm { 0, 4, 8, 16, 32, 64, 128, 192 }; 2734231200Smm static const unsigned char shortbits[] = 2735231200Smm { 2, 2, 3, 4, 5, 6, 6, 6 }; 2736231200Smm 2737231200Smm int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol; 2738231200Smm unsigned char newfile; 2739231200Smm struct rar *rar = (struct rar *)(a->format->data); 2740231200Smm struct rar_br *br = &(rar->br); 2741231200Smm 2742231200Smm if (rar->filterstart < end) 2743231200Smm end = rar->filterstart; 2744231200Smm 2745231200Smm while (1) 2746231200Smm { 2747231200Smm if (rar->output_last_match && 2748231200Smm lzss_position(&rar->lzss) + rar->lastlength <= end) 2749231200Smm { 2750231200Smm lzss_emit_match(rar, rar->lastoffset, rar->lastlength); 2751231200Smm rar->output_last_match = 0; 2752231200Smm } 2753231200Smm 2754231200Smm if(rar->is_ppmd_block || rar->output_last_match || 2755231200Smm lzss_position(&rar->lzss) >= end) 2756231200Smm return lzss_position(&rar->lzss); 2757231200Smm 2758231200Smm if ((symbol = read_next_symbol(a, &rar->maincode)) < 0) 2759231200Smm return (ARCHIVE_FATAL); 2760231200Smm rar->output_last_match = 0; 2761299529Smm 2762231200Smm if (symbol < 256) 2763231200Smm { 2764231200Smm lzss_emit_literal(rar, symbol); 2765231200Smm continue; 2766231200Smm } 2767231200Smm else if (symbol == 256) 2768231200Smm { 2769231200Smm if (!rar_br_read_ahead(a, br, 1)) 2770231200Smm goto truncated_data; 2771231200Smm newfile = !rar_br_bits(br, 1); 2772231200Smm rar_br_consume(br, 1); 2773231200Smm 2774231200Smm if(newfile) 2775231200Smm { 2776231200Smm rar->start_new_block = 1; 2777231200Smm if (!rar_br_read_ahead(a, br, 1)) 2778231200Smm goto truncated_data; 2779231200Smm rar->start_new_table = rar_br_bits(br, 1); 2780231200Smm rar_br_consume(br, 1); 2781231200Smm return lzss_position(&rar->lzss); 2782231200Smm } 2783231200Smm else 2784231200Smm { 2785231200Smm if (parse_codes(a) != ARCHIVE_OK) 2786231200Smm return (ARCHIVE_FATAL); 2787231200Smm continue; 2788231200Smm } 2789231200Smm } 2790231200Smm else if(symbol==257) 2791231200Smm { 2792231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 2793231200Smm "Parsing filters is unsupported."); 2794231200Smm return (ARCHIVE_FAILED); 2795231200Smm } 2796231200Smm else if(symbol==258) 2797231200Smm { 2798231200Smm if(rar->lastlength == 0) 2799231200Smm continue; 2800231200Smm 2801231200Smm offs = rar->lastoffset; 2802231200Smm len = rar->lastlength; 2803231200Smm } 2804231200Smm else if (symbol <= 262) 2805231200Smm { 2806231200Smm offsindex = symbol - 259; 2807231200Smm offs = rar->oldoffset[offsindex]; 2808231200Smm 2809231200Smm if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0) 2810231200Smm goto bad_data; 2811358088Smm if (lensymbol > lengthb_min) 2812231200Smm goto bad_data; 2813231200Smm len = lengthbases[lensymbol] + 2; 2814231200Smm if (lengthbits[lensymbol] > 0) { 2815231200Smm if (!rar_br_read_ahead(a, br, lengthbits[lensymbol])) 2816231200Smm goto truncated_data; 2817231200Smm len += rar_br_bits(br, lengthbits[lensymbol]); 2818231200Smm rar_br_consume(br, lengthbits[lensymbol]); 2819231200Smm } 2820231200Smm 2821231200Smm for (i = offsindex; i > 0; i--) 2822231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2823231200Smm rar->oldoffset[0] = offs; 2824231200Smm } 2825231200Smm else if(symbol<=270) 2826231200Smm { 2827231200Smm offs = shortbases[symbol-263] + 1; 2828231200Smm if(shortbits[symbol-263] > 0) { 2829231200Smm if (!rar_br_read_ahead(a, br, shortbits[symbol-263])) 2830231200Smm goto truncated_data; 2831231200Smm offs += rar_br_bits(br, shortbits[symbol-263]); 2832231200Smm rar_br_consume(br, shortbits[symbol-263]); 2833231200Smm } 2834231200Smm 2835231200Smm len = 2; 2836231200Smm 2837231200Smm for(i = 3; i > 0; i--) 2838231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2839231200Smm rar->oldoffset[0] = offs; 2840231200Smm } 2841231200Smm else 2842231200Smm { 2843358088Smm if (symbol-271 > lengthb_min) 2844231200Smm goto bad_data; 2845231200Smm len = lengthbases[symbol-271]+3; 2846231200Smm if(lengthbits[symbol-271] > 0) { 2847231200Smm if (!rar_br_read_ahead(a, br, lengthbits[symbol-271])) 2848231200Smm goto truncated_data; 2849231200Smm len += rar_br_bits(br, lengthbits[symbol-271]); 2850231200Smm rar_br_consume(br, lengthbits[symbol-271]); 2851231200Smm } 2852231200Smm 2853231200Smm if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0) 2854231200Smm goto bad_data; 2855358088Smm if (offssymbol > offsetb_min) 2856231200Smm goto bad_data; 2857231200Smm offs = offsetbases[offssymbol]+1; 2858231200Smm if(offsetbits[offssymbol] > 0) 2859231200Smm { 2860231200Smm if(offssymbol > 9) 2861231200Smm { 2862231200Smm if(offsetbits[offssymbol] > 4) { 2863231200Smm if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4)) 2864231200Smm goto truncated_data; 2865231200Smm offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4; 2866231200Smm rar_br_consume(br, offsetbits[offssymbol] - 4); 2867231200Smm } 2868231200Smm 2869231200Smm if(rar->numlowoffsetrepeats > 0) 2870231200Smm { 2871231200Smm rar->numlowoffsetrepeats--; 2872231200Smm offs += rar->lastlowoffset; 2873231200Smm } 2874231200Smm else 2875231200Smm { 2876231200Smm if ((lowoffsetsymbol = 2877231200Smm read_next_symbol(a, &rar->lowoffsetcode)) < 0) 2878231200Smm return (ARCHIVE_FATAL); 2879231200Smm if(lowoffsetsymbol == 16) 2880231200Smm { 2881231200Smm rar->numlowoffsetrepeats = 15; 2882231200Smm offs += rar->lastlowoffset; 2883231200Smm } 2884231200Smm else 2885231200Smm { 2886231200Smm offs += lowoffsetsymbol; 2887231200Smm rar->lastlowoffset = lowoffsetsymbol; 2888231200Smm } 2889231200Smm } 2890231200Smm } 2891231200Smm else { 2892231200Smm if (!rar_br_read_ahead(a, br, offsetbits[offssymbol])) 2893231200Smm goto truncated_data; 2894231200Smm offs += rar_br_bits(br, offsetbits[offssymbol]); 2895231200Smm rar_br_consume(br, offsetbits[offssymbol]); 2896231200Smm } 2897231200Smm } 2898231200Smm 2899231200Smm if (offs >= 0x40000) 2900231200Smm len++; 2901231200Smm if (offs >= 0x2000) 2902231200Smm len++; 2903231200Smm 2904231200Smm for(i = 3; i > 0; i--) 2905231200Smm rar->oldoffset[i] = rar->oldoffset[i-1]; 2906231200Smm rar->oldoffset[0] = offs; 2907231200Smm } 2908231200Smm 2909231200Smm rar->lastoffset = offs; 2910231200Smm rar->lastlength = len; 2911231200Smm rar->output_last_match = 1; 2912231200Smm } 2913231200Smmtruncated_data: 2914231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2915231200Smm "Truncated RAR file data"); 2916231200Smm rar->valid = 0; 2917231200Smm return (ARCHIVE_FATAL); 2918231200Smmbad_data: 2919231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2920231200Smm "Bad RAR file data"); 2921231200Smm return (ARCHIVE_FATAL); 2922231200Smm} 2923231200Smm 2924231200Smmstatic int 2925231200Smmcopy_from_lzss_window(struct archive_read *a, const void **buffer, 2926231200Smm int64_t startpos, int length) 2927231200Smm{ 2928231200Smm int windowoffs, firstpart; 2929231200Smm struct rar *rar = (struct rar *)(a->format->data); 2930231200Smm 2931231200Smm if (!rar->unp_buffer) 2932231200Smm { 2933231200Smm if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL) 2934231200Smm { 2935231200Smm archive_set_error(&a->archive, ENOMEM, 2936231200Smm "Unable to allocate memory for uncompressed data."); 2937231200Smm return (ARCHIVE_FATAL); 2938231200Smm } 2939231200Smm } 2940231200Smm 2941231200Smm windowoffs = lzss_offset_for_position(&rar->lzss, startpos); 2942302075Smm if(windowoffs + length <= lzss_size(&rar->lzss)) { 2943231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs], 2944231200Smm length); 2945302075Smm } else if (length <= lzss_size(&rar->lzss)) { 2946231200Smm firstpart = lzss_size(&rar->lzss) - windowoffs; 2947231200Smm if (firstpart < 0) { 2948231200Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2949231200Smm "Bad RAR file data"); 2950231200Smm return (ARCHIVE_FATAL); 2951231200Smm } 2952231200Smm if (firstpart < length) { 2953231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], 2954231200Smm &rar->lzss.window[windowoffs], firstpart); 2955231200Smm memcpy(&rar->unp_buffer[rar->unp_offset + firstpart], 2956231200Smm &rar->lzss.window[0], length - firstpart); 2957302075Smm } else { 2958231200Smm memcpy(&rar->unp_buffer[rar->unp_offset], 2959231200Smm &rar->lzss.window[windowoffs], length); 2960302075Smm } 2961302075Smm } else { 2962302075Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 2963302075Smm "Bad RAR file data"); 2964302075Smm return (ARCHIVE_FATAL); 2965231200Smm } 2966231200Smm rar->unp_offset += length; 2967231200Smm if (rar->unp_offset >= rar->unp_buffer_size) 2968231200Smm *buffer = rar->unp_buffer; 2969231200Smm else 2970231200Smm *buffer = NULL; 2971231200Smm return (ARCHIVE_OK); 2972231200Smm} 2973248616Smm 2974248616Smmstatic const void * 2975248616Smmrar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail) 2976248616Smm{ 2977248616Smm struct rar *rar = (struct rar *)(a->format->data); 2978248616Smm const void *h = __archive_read_ahead(a, min, avail); 2979248616Smm int ret; 2980248616Smm if (avail) 2981248616Smm { 2982299529Smm if (a->archive.read_data_is_posix_read && *avail > (ssize_t)a->archive.read_data_requested) 2983299529Smm *avail = a->archive.read_data_requested; 2984248616Smm if (*avail > rar->bytes_remaining) 2985248616Smm *avail = (ssize_t)rar->bytes_remaining; 2986248616Smm if (*avail < 0) 2987248616Smm return NULL; 2988248616Smm else if (*avail == 0 && rar->main_flags & MHD_VOLUME && 2989248616Smm rar->file_flags & FHD_SPLIT_AFTER) 2990248616Smm { 2991342360Smm rar->filename_must_match = 1; 2992248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 2993248616Smm if (ret == (ARCHIVE_EOF)) 2994248616Smm { 2995248616Smm rar->has_endarc_header = 1; 2996248616Smm ret = archive_read_format_rar_read_header(a, a->entry); 2997248616Smm } 2998342360Smm rar->filename_must_match = 0; 2999248616Smm if (ret != (ARCHIVE_OK)) 3000248616Smm return NULL; 3001248616Smm return rar_read_ahead(a, min, avail); 3002248616Smm } 3003248616Smm } 3004248616Smm return h; 3005248616Smm} 3006