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