archive_read_support_format_rar.c revision 231200
1231200Smm/*-
2231200Smm* Copyright (c) 2003-2007 Tim Kientzle
3231200Smm* Copyright (c) 2011 Andres Mejia
4231200Smm* All rights reserved.
5231200Smm*
6231200Smm* Redistribution and use in source and binary forms, with or without
7231200Smm* modification, are permitted provided that the following conditions
8231200Smm* are met:
9231200Smm* 1. Redistributions of source code must retain the above copyright
10231200Smm*    notice, this list of conditions and the following disclaimer.
11231200Smm* 2. Redistributions in binary form must reproduce the above copyright
12231200Smm*    notice, this list of conditions and the following disclaimer in the
13231200Smm*    documentation and/or other materials provided with the distribution.
14231200Smm*
15231200Smm* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16231200Smm* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17231200Smm* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18231200Smm* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19231200Smm* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20231200Smm* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21231200Smm* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22231200Smm* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23231200Smm* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24231200Smm* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25231200Smm*/
26231200Smm
27231200Smm#include "archive_platform.h"
28231200Smm
29231200Smm#ifdef HAVE_ERRNO_H
30231200Smm#include <errno.h>
31231200Smm#endif
32231200Smm#include <time.h>
33231200Smm#include <limits.h>
34231200Smm#ifdef HAVE_ZLIB_H
35231200Smm#include <zlib.h> /* crc32 */
36231200Smm#endif
37231200Smm
38231200Smm#include "archive.h"
39231200Smm#ifndef HAVE_ZLIB_H
40231200Smm#include "archive_crc32.h"
41231200Smm#endif
42231200Smm#include "archive_endian.h"
43231200Smm#include "archive_entry.h"
44231200Smm#include "archive_entry_locale.h"
45231200Smm#include "archive_ppmd7_private.h"
46231200Smm#include "archive_private.h"
47231200Smm#include "archive_read_private.h"
48231200Smm
49231200Smm/* RAR signature, also known as the mark header */
50231200Smm#define RAR_SIGNATURE "\x52\x61\x72\x21\x1A\x07\x00"
51231200Smm
52231200Smm/* Header types */
53231200Smm#define MARK_HEAD    0x72
54231200Smm#define MAIN_HEAD    0x73
55231200Smm#define FILE_HEAD    0x74
56231200Smm#define COMM_HEAD    0x75
57231200Smm#define AV_HEAD      0x76
58231200Smm#define SUB_HEAD     0x77
59231200Smm#define PROTECT_HEAD 0x78
60231200Smm#define SIGN_HEAD    0x79
61231200Smm#define NEWSUB_HEAD  0x7a
62231200Smm#define ENDARC_HEAD  0x7b
63231200Smm
64231200Smm/* Main Header Flags */
65231200Smm#define MHD_VOLUME       0x0001
66231200Smm#define MHD_COMMENT      0x0002
67231200Smm#define MHD_LOCK         0x0004
68231200Smm#define MHD_SOLID        0x0008
69231200Smm#define MHD_NEWNUMBERING 0x0010
70231200Smm#define MHD_AV           0x0020
71231200Smm#define MHD_PROTECT      0x0040
72231200Smm#define MHD_PASSWORD     0x0080
73231200Smm#define MHD_FIRSTVOLUME  0x0100
74231200Smm#define MHD_ENCRYPTVER   0x0200
75231200Smm
76231200Smm/* Flags common to all headers */
77231200Smm#define HD_MARKDELETION     0x4000
78231200Smm#define HD_ADD_SIZE_PRESENT 0x8000
79231200Smm
80231200Smm/* File Header Flags */
81231200Smm#define FHD_SPLIT_BEFORE 0x0001
82231200Smm#define FHD_SPLIT_AFTER  0x0002
83231200Smm#define FHD_PASSWORD     0x0004
84231200Smm#define FHD_COMMENT      0x0008
85231200Smm#define FHD_SOLID        0x0010
86231200Smm#define FHD_LARGE        0x0100
87231200Smm#define FHD_UNICODE      0x0200
88231200Smm#define FHD_SALT         0x0400
89231200Smm#define FHD_VERSION      0x0800
90231200Smm#define FHD_EXTTIME      0x1000
91231200Smm#define FHD_EXTFLAGS     0x2000
92231200Smm
93231200Smm/* File dictionary sizes */
94231200Smm#define DICTIONARY_SIZE_64   0x00
95231200Smm#define DICTIONARY_SIZE_128  0x20
96231200Smm#define DICTIONARY_SIZE_256  0x40
97231200Smm#define DICTIONARY_SIZE_512  0x60
98231200Smm#define DICTIONARY_SIZE_1024 0x80
99231200Smm#define DICTIONARY_SIZE_2048 0xA0
100231200Smm#define DICTIONARY_SIZE_4096 0xC0
101231200Smm#define FILE_IS_DIRECTORY    0xE0
102231200Smm#define DICTIONARY_MASK      FILE_IS_DIRECTORY
103231200Smm
104231200Smm/* OS Flags */
105231200Smm#define OS_MSDOS  0
106231200Smm#define OS_OS2    1
107231200Smm#define OS_WIN32  2
108231200Smm#define OS_UNIX   3
109231200Smm#define OS_MAC_OS 4
110231200Smm#define OS_BEOS   5
111231200Smm
112231200Smm/* Compression Methods */
113231200Smm#define COMPRESS_METHOD_STORE   0x30
114231200Smm/* LZSS */
115231200Smm#define COMPRESS_METHOD_FASTEST 0x31
116231200Smm#define COMPRESS_METHOD_FAST    0x32
117231200Smm#define COMPRESS_METHOD_NORMAL  0x33
118231200Smm/* PPMd Variant H */
119231200Smm#define COMPRESS_METHOD_GOOD    0x34
120231200Smm#define COMPRESS_METHOD_BEST    0x35
121231200Smm
122231200Smm#define CRC_POLYNOMIAL 0xEDB88320
123231200Smm
124231200Smm#define NS_UNIT 10000000
125231200Smm
126231200Smm#define DICTIONARY_MAX_SIZE 0x400000
127231200Smm
128231200Smm#define MAINCODE_SIZE      299
129231200Smm#define OFFSETCODE_SIZE    60
130231200Smm#define LOWOFFSETCODE_SIZE 17
131231200Smm#define LENGTHCODE_SIZE    28
132231200Smm#define HUFFMAN_TABLE_SIZE \
133231200Smm  MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE + LENGTHCODE_SIZE
134231200Smm
135231200Smm#define MAX_SYMBOL_LENGTH 0xF
136231200Smm#define MAX_SYMBOLS       20
137231200Smm
138231200Smm/*
139231200Smm * Considering L1,L2 cache miss and a calling of write system-call,
140231200Smm * the best size of the output buffer(uncompressed buffer) is 128K.
141231200Smm * If the structure of extracting process is changed, this value
142231200Smm * might be researched again.
143231200Smm */
144231200Smm#define UNP_BUFFER_SIZE   (128 * 1024)
145231200Smm
146231200Smm/* Define this here for non-Windows platforms */
147231200Smm#if !((defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__))
148231200Smm#define FILE_ATTRIBUTE_DIRECTORY 0x10
149231200Smm#endif
150231200Smm
151231200Smm/* Fields common to all headers */
152231200Smmstruct rar_header
153231200Smm{
154231200Smm  char crc[2];
155231200Smm  char type;
156231200Smm  char flags[2];
157231200Smm  char size[2];
158231200Smm};
159231200Smm
160231200Smm/* Fields common to all file headers */
161231200Smmstruct rar_file_header
162231200Smm{
163231200Smm  char pack_size[4];
164231200Smm  char unp_size[4];
165231200Smm  char host_os;
166231200Smm  char file_crc[4];
167231200Smm  char file_time[4];
168231200Smm  char unp_ver;
169231200Smm  char method;
170231200Smm  char name_size[2];
171231200Smm  char file_attr[4];
172231200Smm};
173231200Smm
174231200Smmstruct huffman_tree_node
175231200Smm{
176231200Smm  int branches[2];
177231200Smm};
178231200Smm
179231200Smmstruct huffman_table_entry
180231200Smm{
181231200Smm  unsigned int length;
182231200Smm  int value;
183231200Smm};
184231200Smm
185231200Smmstruct huffman_code
186231200Smm{
187231200Smm  struct huffman_tree_node *tree;
188231200Smm  int numentries;
189231200Smm  int minlength;
190231200Smm  int maxlength;
191231200Smm  int tablesize;
192231200Smm  struct huffman_table_entry *table;
193231200Smm};
194231200Smm
195231200Smmstruct lzss
196231200Smm{
197231200Smm  unsigned char *window;
198231200Smm  int mask;
199231200Smm  int64_t position;
200231200Smm};
201231200Smm
202231200Smmstruct rar
203231200Smm{
204231200Smm  /* Entries from main RAR header */
205231200Smm  unsigned main_flags;
206231200Smm  unsigned long file_crc;
207231200Smm  char reserved1[2];
208231200Smm  char reserved2[4];
209231200Smm  char encryptver;
210231200Smm
211231200Smm  /* File header entries */
212231200Smm  char compression_method;
213231200Smm  unsigned file_flags;
214231200Smm  int64_t packed_size;
215231200Smm  int64_t unp_size;
216231200Smm  time_t mtime;
217231200Smm  long mnsec;
218231200Smm  mode_t mode;
219231200Smm  char *filename;
220231200Smm  size_t filename_allocated;
221231200Smm
222231200Smm  /* File header optional entries */
223231200Smm  char salt[8];
224231200Smm  time_t atime;
225231200Smm  long ansec;
226231200Smm  time_t ctime;
227231200Smm  long cnsec;
228231200Smm  time_t arctime;
229231200Smm  long arcnsec;
230231200Smm
231231200Smm  /* Fields to help with tracking decompression of files. */
232231200Smm  int64_t bytes_unconsumed;
233231200Smm  int64_t bytes_remaining;
234231200Smm  int64_t bytes_uncopied;
235231200Smm  int64_t offset;
236231200Smm  int64_t offset_outgoing;
237231200Smm  char valid;
238231200Smm  unsigned int unp_offset;
239231200Smm  unsigned int unp_buffer_size;
240231200Smm  unsigned char *unp_buffer;
241231200Smm  unsigned int dictionary_size;
242231200Smm  char start_new_block;
243231200Smm  char entry_eof;
244231200Smm  unsigned long crc_calculated;
245231200Smm  int found_first_header;
246231200Smm
247231200Smm  /* LZSS members */
248231200Smm  struct huffman_code maincode;
249231200Smm  struct huffman_code offsetcode;
250231200Smm  struct huffman_code lowoffsetcode;
251231200Smm  struct huffman_code lengthcode;
252231200Smm  unsigned char lengthtable[HUFFMAN_TABLE_SIZE];
253231200Smm  struct lzss lzss;
254231200Smm  char output_last_match;
255231200Smm  unsigned int lastlength;
256231200Smm  unsigned int lastoffset;
257231200Smm  unsigned int oldoffset[4];
258231200Smm  unsigned int lastlowoffset;
259231200Smm  unsigned int numlowoffsetrepeats;
260231200Smm  int64_t filterstart;
261231200Smm  char start_new_table;
262231200Smm
263231200Smm  /* PPMd Variant H members */
264231200Smm  char ppmd_valid;
265231200Smm  char ppmd_eod;
266231200Smm  char is_ppmd_block;
267231200Smm  int ppmd_escape;
268231200Smm  CPpmd7 ppmd7_context;
269231200Smm  CPpmd7z_RangeDec range_dec;
270231200Smm  IByteIn bytein;
271231200Smm
272231200Smm  /*
273231200Smm   * String conversion object.
274231200Smm   */
275231200Smm  int init_default_conversion;
276231200Smm  struct archive_string_conv *sconv_default;
277231200Smm  struct archive_string_conv *opt_sconv;
278231200Smm  struct archive_string_conv *sconv_utf8;
279231200Smm  struct archive_string_conv *sconv_utf16be;
280231200Smm
281231200Smm  /*
282231200Smm   * Bit stream reader.
283231200Smm   */
284231200Smm  struct rar_br {
285231200Smm#define CACHE_TYPE	uint64_t
286231200Smm#define CACHE_BITS	(8 * sizeof(CACHE_TYPE))
287231200Smm    /* Cache buffer. */
288231200Smm    CACHE_TYPE		 cache_buffer;
289231200Smm    /* Indicates how many bits avail in cache_buffer. */
290231200Smm    int			 cache_avail;
291231200Smm    ssize_t		 avail_in;
292231200Smm    const unsigned char *next_in;
293231200Smm  } br;
294231200Smm};
295231200Smm
296231200Smmstatic int archive_read_format_rar_bid(struct archive_read *, int);
297231200Smmstatic int archive_read_format_rar_options(struct archive_read *,
298231200Smm    const char *, const char *);
299231200Smmstatic int archive_read_format_rar_read_header(struct archive_read *,
300231200Smm    struct archive_entry *);
301231200Smmstatic int archive_read_format_rar_read_data(struct archive_read *,
302231200Smm    const void **, size_t *, int64_t *);
303231200Smmstatic int archive_read_format_rar_read_data_skip(struct archive_read *a);
304231200Smmstatic int archive_read_format_rar_cleanup(struct archive_read *);
305231200Smm
306231200Smm/* Support functions */
307231200Smmstatic int read_header(struct archive_read *, struct archive_entry *, char);
308231200Smmstatic time_t get_time(int time);
309231200Smmstatic int read_exttime(const char *, struct rar *, const char *);
310231200Smmstatic int read_symlink_stored(struct archive_read *, struct archive_entry *,
311231200Smm                               struct archive_string_conv *);
312231200Smmstatic int read_data_stored(struct archive_read *, const void **, size_t *,
313231200Smm                            int64_t *);
314231200Smmstatic int read_data_compressed(struct archive_read *, const void **, size_t *,
315231200Smm                          int64_t *);
316231200Smmstatic int rar_br_preparation(struct archive_read *, struct rar_br *);
317231200Smmstatic int parse_codes(struct archive_read *);
318231200Smmstatic void free_codes(struct archive_read *);
319231200Smmstatic int read_next_symbol(struct archive_read *, struct huffman_code *);
320231200Smmstatic int create_code(struct archive_read *, struct huffman_code *,
321231200Smm                        unsigned char *, int, char);
322231200Smmstatic int add_value(struct archive_read *, struct huffman_code *, int, int,
323231200Smm                     int);
324231200Smmstatic int new_node(struct huffman_code *);
325231200Smmstatic int make_table(struct archive_read *, struct huffman_code *);
326231200Smmstatic int make_table_recurse(struct archive_read *, struct huffman_code *, int,
327231200Smm                              struct huffman_table_entry *, int, int);
328231200Smmstatic int64_t expand(struct archive_read *, int64_t);
329231200Smmstatic int copy_from_lzss_window(struct archive_read *, const void **,
330231200Smm                                   int64_t, int);
331231200Smm
332231200Smm/*
333231200Smm * Bit stream reader.
334231200Smm */
335231200Smm/* Check that the cache buffer has enough bits. */
336231200Smm#define rar_br_has(br, n) ((br)->cache_avail >= n)
337231200Smm/* Get compressed data by bit. */
338231200Smm#define rar_br_bits(br, n)        \
339231200Smm  (((uint32_t)((br)->cache_buffer >>    \
340231200Smm    ((br)->cache_avail - (n)))) & cache_masks[n])
341231200Smm#define rar_br_bits_forced(br, n)     \
342231200Smm  (((uint32_t)((br)->cache_buffer <<    \
343231200Smm    ((n) - (br)->cache_avail))) & cache_masks[n])
344231200Smm/* Read ahead to make sure the cache buffer has enough compressed data we
345231200Smm * will use.
346231200Smm *  True  : completed, there is enough data in the cache buffer.
347231200Smm *  False : there is no data in the stream. */
348231200Smm#define rar_br_read_ahead(a, br, n) \
349231200Smm  ((rar_br_has(br, (n)) || rar_br_fillup(a, br)) || rar_br_has(br, (n)))
350231200Smm/* Notify how many bits we consumed. */
351231200Smm#define rar_br_consume(br, n) ((br)->cache_avail -= (n))
352231200Smm#define rar_br_consume_unalined_bits(br) ((br)->cache_avail &= ~7)
353231200Smm
354231200Smmstatic const uint32_t cache_masks[] = {
355231200Smm  0x00000000, 0x00000001, 0x00000003, 0x00000007,
356231200Smm  0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
357231200Smm  0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
358231200Smm  0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
359231200Smm  0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
360231200Smm  0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
361231200Smm  0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
362231200Smm  0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
363231200Smm  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
364231200Smm};
365231200Smm
366231200Smm/*
367231200Smm * Shift away used bits in the cache data and fill it up with following bits.
368231200Smm * Call this when cache buffer does not have enough bits you need.
369231200Smm *
370231200Smm * Returns 1 if the cache buffer is full.
371231200Smm * Returns 0 if the cache buffer is not full; input buffer is empty.
372231200Smm */
373231200Smmstatic int
374231200Smmrar_br_fillup(struct archive_read *a, struct rar_br *br)
375231200Smm{
376231200Smm  struct rar *rar = (struct rar *)(a->format->data);
377231200Smm  int n = CACHE_BITS - br->cache_avail;
378231200Smm
379231200Smm  for (;;) {
380231200Smm    switch (n >> 3) {
381231200Smm    case 8:
382231200Smm      if (br->avail_in >= 8) {
383231200Smm        br->cache_buffer =
384231200Smm            ((uint64_t)br->next_in[0]) << 56 |
385231200Smm            ((uint64_t)br->next_in[1]) << 48 |
386231200Smm            ((uint64_t)br->next_in[2]) << 40 |
387231200Smm            ((uint64_t)br->next_in[3]) << 32 |
388231200Smm            ((uint32_t)br->next_in[4]) << 24 |
389231200Smm            ((uint32_t)br->next_in[5]) << 16 |
390231200Smm            ((uint32_t)br->next_in[6]) << 8 |
391231200Smm             (uint32_t)br->next_in[7];
392231200Smm        br->next_in += 8;
393231200Smm        br->avail_in -= 8;
394231200Smm        br->cache_avail += 8 * 8;
395231200Smm        rar->bytes_unconsumed += 8;
396231200Smm        rar->bytes_remaining -= 8;
397231200Smm        return (1);
398231200Smm      }
399231200Smm      break;
400231200Smm    case 7:
401231200Smm      if (br->avail_in >= 7) {
402231200Smm        br->cache_buffer =
403231200Smm           (br->cache_buffer << 56) |
404231200Smm            ((uint64_t)br->next_in[0]) << 48 |
405231200Smm            ((uint64_t)br->next_in[1]) << 40 |
406231200Smm            ((uint64_t)br->next_in[2]) << 32 |
407231200Smm            ((uint32_t)br->next_in[3]) << 24 |
408231200Smm            ((uint32_t)br->next_in[4]) << 16 |
409231200Smm            ((uint32_t)br->next_in[5]) << 8 |
410231200Smm             (uint32_t)br->next_in[6];
411231200Smm        br->next_in += 7;
412231200Smm        br->avail_in -= 7;
413231200Smm        br->cache_avail += 7 * 8;
414231200Smm        rar->bytes_unconsumed += 7;
415231200Smm        rar->bytes_remaining -= 7;
416231200Smm        return (1);
417231200Smm      }
418231200Smm      break;
419231200Smm    case 6:
420231200Smm      if (br->avail_in >= 6) {
421231200Smm        br->cache_buffer =
422231200Smm           (br->cache_buffer << 48) |
423231200Smm            ((uint64_t)br->next_in[0]) << 40 |
424231200Smm            ((uint64_t)br->next_in[1]) << 32 |
425231200Smm            ((uint32_t)br->next_in[2]) << 24 |
426231200Smm            ((uint32_t)br->next_in[3]) << 16 |
427231200Smm            ((uint32_t)br->next_in[4]) << 8 |
428231200Smm             (uint32_t)br->next_in[5];
429231200Smm        br->next_in += 6;
430231200Smm        br->avail_in -= 6;
431231200Smm        br->cache_avail += 6 * 8;
432231200Smm        rar->bytes_unconsumed += 6;
433231200Smm        rar->bytes_remaining -= 6;
434231200Smm        return (1);
435231200Smm      }
436231200Smm      break;
437231200Smm    case 0:
438231200Smm      /* We have enough compressed data in
439231200Smm       * the cache buffer.*/
440231200Smm      return (1);
441231200Smm    default:
442231200Smm      break;
443231200Smm    }
444231200Smm    if (br->avail_in <= 0) {
445231200Smm
446231200Smm      if (rar->bytes_unconsumed > 0) {
447231200Smm        /* Consume as much as the decompressor
448231200Smm         * actually used. */
449231200Smm        __archive_read_consume(a, rar->bytes_unconsumed);
450231200Smm        rar->bytes_unconsumed = 0;
451231200Smm      }
452231200Smm      br->next_in = __archive_read_ahead(a, 1, &(br->avail_in));
453231200Smm      if (br->next_in == NULL)
454231200Smm        return (0);
455231200Smm      if (br->avail_in > rar->bytes_remaining)
456231200Smm        br->avail_in = rar->bytes_remaining;
457231200Smm      if (br->avail_in == 0)
458231200Smm        return (0);
459231200Smm    }
460231200Smm    br->cache_buffer =
461231200Smm       (br->cache_buffer << 8) | *br->next_in++;
462231200Smm    br->avail_in--;
463231200Smm    br->cache_avail += 8;
464231200Smm    n -= 8;
465231200Smm    rar->bytes_unconsumed++;
466231200Smm    rar->bytes_remaining--;
467231200Smm  }
468231200Smm}
469231200Smm
470231200Smmstatic int
471231200Smmrar_br_preparation(struct archive_read *a, struct rar_br *br)
472231200Smm{
473231200Smm  struct rar *rar = (struct rar *)(a->format->data);
474231200Smm
475231200Smm  if (rar->bytes_remaining > 0) {
476231200Smm    br->next_in = __archive_read_ahead(a, 1, &(br->avail_in));
477231200Smm    if (br->next_in == NULL) {
478231200Smm      archive_set_error(&a->archive,
479231200Smm          ARCHIVE_ERRNO_FILE_FORMAT,
480231200Smm          "Truncated RAR file data");
481231200Smm      return (ARCHIVE_FATAL);
482231200Smm    }
483231200Smm    if (br->avail_in > rar->bytes_remaining)
484231200Smm      br->avail_in = rar->bytes_remaining;
485231200Smm    if (br->cache_avail == 0)
486231200Smm      (void)rar_br_fillup(a, br);
487231200Smm  }
488231200Smm  return (ARCHIVE_OK);
489231200Smm}
490231200Smm
491231200Smm/* Find last bit set */
492231200Smmstatic inline int
493231200Smmrar_fls(unsigned int word)
494231200Smm{
495231200Smm  word |= (word >>  1);
496231200Smm  word |= (word >>  2);
497231200Smm  word |= (word >>  4);
498231200Smm  word |= (word >>  8);
499231200Smm  word |= (word >> 16);
500231200Smm  return word - (word >> 1);
501231200Smm}
502231200Smm
503231200Smm/* LZSS functions */
504231200Smmstatic inline int64_t
505231200Smmlzss_position(struct lzss *lzss)
506231200Smm{
507231200Smm  return lzss->position;
508231200Smm}
509231200Smm
510231200Smmstatic inline int
511231200Smmlzss_mask(struct lzss *lzss)
512231200Smm{
513231200Smm  return lzss->mask;
514231200Smm}
515231200Smm
516231200Smmstatic inline int
517231200Smmlzss_size(struct lzss *lzss)
518231200Smm{
519231200Smm  return lzss->mask + 1;
520231200Smm}
521231200Smm
522231200Smmstatic inline int
523231200Smmlzss_offset_for_position(struct lzss *lzss, int64_t pos)
524231200Smm{
525231200Smm  return pos & lzss->mask;
526231200Smm}
527231200Smm
528231200Smmstatic inline unsigned char *
529231200Smmlzss_pointer_for_position(struct lzss *lzss, int64_t pos)
530231200Smm{
531231200Smm  return &lzss->window[lzss_offset_for_position(lzss, pos)];
532231200Smm}
533231200Smm
534231200Smmstatic inline int
535231200Smmlzss_current_offset(struct lzss *lzss)
536231200Smm{
537231200Smm  return lzss_offset_for_position(lzss, lzss->position);
538231200Smm}
539231200Smm
540231200Smmstatic inline uint8_t *
541231200Smmlzss_current_pointer(struct lzss *lzss)
542231200Smm{
543231200Smm  return lzss_pointer_for_position(lzss, lzss->position);
544231200Smm}
545231200Smm
546231200Smmstatic inline void
547231200Smmlzss_emit_literal(struct rar *rar, uint8_t literal)
548231200Smm{
549231200Smm  *lzss_current_pointer(&rar->lzss) = literal;
550231200Smm  rar->lzss.position++;
551231200Smm}
552231200Smm
553231200Smmstatic inline void
554231200Smmlzss_emit_match(struct rar *rar, int offset, int length)
555231200Smm{
556231200Smm  int dstoffs = lzss_current_offset(&rar->lzss);
557231200Smm  int srcoffs = (dstoffs - offset) & lzss_mask(&rar->lzss);
558231200Smm  int l, li, remaining;
559231200Smm  unsigned char *d, *s;
560231200Smm
561231200Smm  remaining = length;
562231200Smm  while (remaining > 0) {
563231200Smm    l = remaining;
564231200Smm    if (dstoffs > srcoffs) {
565231200Smm      if (l > lzss_size(&rar->lzss) - dstoffs)
566231200Smm        l = lzss_size(&rar->lzss) - dstoffs;
567231200Smm    } else {
568231200Smm      if (l > lzss_size(&rar->lzss) - srcoffs)
569231200Smm        l = lzss_size(&rar->lzss) - srcoffs;
570231200Smm    }
571231200Smm    d = &(rar->lzss.window[dstoffs]);
572231200Smm    s = &(rar->lzss.window[srcoffs]);
573231200Smm    if ((dstoffs + l < srcoffs) || (srcoffs + l < dstoffs))
574231200Smm      memcpy(d, s, l);
575231200Smm    else {
576231200Smm      for (li = 0; li < l; li++)
577231200Smm        d[li] = s[li];
578231200Smm    }
579231200Smm    remaining -= l;
580231200Smm    dstoffs = (dstoffs + l) & lzss_mask(&(rar->lzss));
581231200Smm    srcoffs = (srcoffs + l) & lzss_mask(&(rar->lzss));
582231200Smm  }
583231200Smm  rar->lzss.position += length;
584231200Smm}
585231200Smm
586231200Smmstatic void *
587231200Smmppmd_alloc(void *p, size_t size)
588231200Smm{
589231200Smm  (void)p;
590231200Smm  return malloc(size);
591231200Smm}
592231200Smmstatic void
593231200Smmppmd_free(void *p, void *address)
594231200Smm{
595231200Smm  (void)p;
596231200Smm  free(address);
597231200Smm}
598231200Smmstatic ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
599231200Smm
600231200Smmstatic Byte
601231200Smmppmd_read(void *p)
602231200Smm{
603231200Smm  struct archive_read *a = ((IByteIn*)p)->a;
604231200Smm  struct rar *rar = (struct rar *)(a->format->data);
605231200Smm  struct rar_br *br = &(rar->br);
606231200Smm  Byte b;
607231200Smm  if (!rar_br_read_ahead(a, br, 8))
608231200Smm  {
609231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
610231200Smm                      "Truncated RAR file data");
611231200Smm    rar->valid = 0;
612231200Smm    return 0;
613231200Smm  }
614231200Smm  b = rar_br_bits(br, 8);
615231200Smm  rar_br_consume(br, 8);
616231200Smm  return b;
617231200Smm}
618231200Smm
619231200Smmint
620231200Smmarchive_read_support_format_rar(struct archive *_a)
621231200Smm{
622231200Smm  struct archive_read *a = (struct archive_read *)_a;
623231200Smm  struct rar *rar;
624231200Smm  int r;
625231200Smm
626231200Smm  archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
627231200Smm                      "archive_read_support_format_rar");
628231200Smm
629231200Smm  rar = (struct rar *)malloc(sizeof(*rar));
630231200Smm  if (rar == NULL)
631231200Smm  {
632231200Smm    archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data");
633231200Smm    return (ARCHIVE_FATAL);
634231200Smm  }
635231200Smm  memset(rar, 0, sizeof(*rar));
636231200Smm
637231200Smm  r = __archive_read_register_format(a,
638231200Smm                                     rar,
639231200Smm                                     "rar",
640231200Smm                                     archive_read_format_rar_bid,
641231200Smm                                     archive_read_format_rar_options,
642231200Smm                                     archive_read_format_rar_read_header,
643231200Smm                                     archive_read_format_rar_read_data,
644231200Smm                                     archive_read_format_rar_read_data_skip,
645231200Smm                                     archive_read_format_rar_cleanup);
646231200Smm
647231200Smm  if (r != ARCHIVE_OK)
648231200Smm    free(rar);
649231200Smm  return (r);
650231200Smm}
651231200Smm
652231200Smmstatic int
653231200Smmarchive_read_format_rar_bid(struct archive_read *a, int best_bid)
654231200Smm{
655231200Smm  const char *p;
656231200Smm
657231200Smm  /* If there's already a bid > 30, we'll never win. */
658231200Smm  if (best_bid > 30)
659231200Smm	  return (-1);
660231200Smm
661231200Smm  if ((p = __archive_read_ahead(a, 7, NULL)) == NULL)
662231200Smm    return (-1);
663231200Smm
664231200Smm  if (memcmp(p, RAR_SIGNATURE, 7) == 0)
665231200Smm    return (30);
666231200Smm
667231200Smm  if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
668231200Smm    /* This is a PE file */
669231200Smm    ssize_t offset = 0x10000;
670231200Smm    ssize_t window = 4096;
671231200Smm    ssize_t bytes_avail;
672231200Smm    while (offset + window <= (1024 * 128)) {
673231200Smm      const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail);
674231200Smm      if (buff == NULL) {
675231200Smm        /* Remaining bytes are less than window. */
676231200Smm        window >>= 1;
677231200Smm        if (window < 0x40)
678231200Smm          return (0);
679231200Smm        continue;
680231200Smm      }
681231200Smm      p = buff + offset;
682231200Smm      while (p + 7 < buff + bytes_avail) {
683231200Smm        if (memcmp(p, RAR_SIGNATURE, 7) == 0)
684231200Smm          return (30);
685231200Smm        p += 0x10;
686231200Smm      }
687231200Smm      offset = p - buff;
688231200Smm    }
689231200Smm  }
690231200Smm  return (0);
691231200Smm}
692231200Smm
693231200Smmstatic int
694231200Smmskip_sfx(struct archive_read *a)
695231200Smm{
696231200Smm  const void *h;
697231200Smm  const char *p, *q;
698231200Smm  size_t skip, total;
699231200Smm  ssize_t bytes, window;
700231200Smm
701231200Smm  total = 0;
702231200Smm  window = 4096;
703231200Smm  while (total + window <= (1024 * 128)) {
704231200Smm    h = __archive_read_ahead(a, window, &bytes);
705231200Smm    if (h == NULL) {
706231200Smm      /* Remaining bytes are less than window. */
707231200Smm      window >>= 1;
708231200Smm      if (window < 0x40)
709231200Smm      	goto fatal;
710231200Smm      continue;
711231200Smm    }
712231200Smm    if (bytes < 0x40)
713231200Smm      goto fatal;
714231200Smm    p = h;
715231200Smm    q = p + bytes;
716231200Smm
717231200Smm    /*
718231200Smm     * Scan ahead until we find something that looks
719231200Smm     * like the RAR header.
720231200Smm     */
721231200Smm    while (p + 7 < q) {
722231200Smm      if (memcmp(p, RAR_SIGNATURE, 7) == 0) {
723231200Smm      	skip = p - (const char *)h;
724231200Smm      	__archive_read_consume(a, skip);
725231200Smm      	return (ARCHIVE_OK);
726231200Smm      }
727231200Smm      p += 0x10;
728231200Smm    }
729231200Smm    skip = p - (const char *)h;
730231200Smm    __archive_read_consume(a, skip);
731231200Smm	total += skip;
732231200Smm  }
733231200Smmfatal:
734231200Smm  archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
735231200Smm      "Couldn't find out RAR header");
736231200Smm  return (ARCHIVE_FATAL);
737231200Smm}
738231200Smm
739231200Smmstatic int
740231200Smmarchive_read_format_rar_options(struct archive_read *a,
741231200Smm    const char *key, const char *val)
742231200Smm{
743231200Smm  struct rar *rar;
744231200Smm  int ret = ARCHIVE_FAILED;
745231200Smm
746231200Smm  rar = (struct rar *)(a->format->data);
747231200Smm  if (strcmp(key, "hdrcharset")  == 0) {
748231200Smm    if (val == NULL || val[0] == 0)
749231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
750231200Smm          "rar: hdrcharset option needs a character-set name");
751231200Smm    else {
752231200Smm      rar->opt_sconv =
753231200Smm          archive_string_conversion_from_charset(
754231200Smm              &a->archive, val, 0);
755231200Smm      if (rar->opt_sconv != NULL)
756231200Smm        ret = ARCHIVE_OK;
757231200Smm      else
758231200Smm        ret = ARCHIVE_FATAL;
759231200Smm    }
760231200Smm  } else
761231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
762231200Smm        "rar: unknown keyword ``%s''", key);
763231200Smm
764231200Smm  return (ret);
765231200Smm}
766231200Smm
767231200Smmstatic int
768231200Smmarchive_read_format_rar_read_header(struct archive_read *a,
769231200Smm                                    struct archive_entry *entry)
770231200Smm{
771231200Smm  const void *h;
772231200Smm  const char *p;
773231200Smm  struct rar *rar;
774231200Smm  size_t skip;
775231200Smm  char head_type;
776231200Smm  int ret;
777231200Smm  unsigned flags;
778231200Smm
779231200Smm  a->archive.archive_format = ARCHIVE_FORMAT_RAR;
780231200Smm  if (a->archive.archive_format_name == NULL)
781231200Smm    a->archive.archive_format_name = "RAR";
782231200Smm
783231200Smm  rar = (struct rar *)(a->format->data);
784231200Smm
785231200Smm  /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if
786231200Smm  * this fails.
787231200Smm  */
788231200Smm  if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
789231200Smm    return (ARCHIVE_EOF);
790231200Smm
791231200Smm  p = h;
792231200Smm  if (rar->found_first_header == 0 &&
793231200Smm     ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) {
794231200Smm    /* This is an executable ? Must be self-extracting... */
795231200Smm    ret = skip_sfx(a);
796231200Smm    if (ret < ARCHIVE_WARN)
797231200Smm      return (ret);
798231200Smm  }
799231200Smm  rar->found_first_header = 1;
800231200Smm
801231200Smm  while (1)
802231200Smm  {
803231200Smm    unsigned long crc32_val;
804231200Smm
805231200Smm    if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
806231200Smm      return (ARCHIVE_FATAL);
807231200Smm    p = h;
808231200Smm
809231200Smm    head_type = p[2];
810231200Smm    switch(head_type)
811231200Smm    {
812231200Smm    case MARK_HEAD:
813231200Smm      if (memcmp(p, RAR_SIGNATURE, 7) != 0) {
814231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
815231200Smm          "Invalid marker header");
816231200Smm        return (ARCHIVE_FATAL);
817231200Smm      }
818231200Smm      __archive_read_consume(a, 7);
819231200Smm      break;
820231200Smm
821231200Smm    case MAIN_HEAD:
822231200Smm      rar->main_flags = archive_le16dec(p + 3);
823231200Smm      skip = archive_le16dec(p + 5);
824231200Smm      if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) {
825231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
826231200Smm          "Invalid header size");
827231200Smm        return (ARCHIVE_FATAL);
828231200Smm      }
829231200Smm      if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
830231200Smm        return (ARCHIVE_FATAL);
831231200Smm      p = h;
832231200Smm      memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1));
833231200Smm      memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1),
834231200Smm             sizeof(rar->reserved2));
835231200Smm      if (rar->main_flags & MHD_ENCRYPTVER) {
836231200Smm        if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) {
837231200Smm          archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
838231200Smm            "Invalid header size");
839231200Smm          return (ARCHIVE_FATAL);
840231200Smm        }
841231200Smm        rar->encryptver = *(p + 7 + sizeof(rar->reserved1) +
842231200Smm                            sizeof(rar->reserved2));
843231200Smm      }
844231200Smm
845231200Smm      if (rar->main_flags & MHD_VOLUME ||
846231200Smm          rar->main_flags & MHD_FIRSTVOLUME)
847231200Smm      {
848231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
849231200Smm                          "RAR volume support unavailable.");
850231200Smm        return (ARCHIVE_FATAL);
851231200Smm      }
852231200Smm      if (rar->main_flags & MHD_PASSWORD)
853231200Smm      {
854231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
855231200Smm                          "RAR encryption support unavailable.");
856231200Smm        return (ARCHIVE_FATAL);
857231200Smm      }
858231200Smm
859231200Smm      crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2);
860231200Smm      if ((crc32_val & 0xffff) != archive_le16dec(p)) {
861231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
862231200Smm          "Header CRC error");
863231200Smm        return (ARCHIVE_FATAL);
864231200Smm      }
865231200Smm      __archive_read_consume(a, skip);
866231200Smm      break;
867231200Smm
868231200Smm    case FILE_HEAD:
869231200Smm      return read_header(a, entry, head_type);
870231200Smm
871231200Smm    case COMM_HEAD:
872231200Smm    case AV_HEAD:
873231200Smm    case SUB_HEAD:
874231200Smm    case PROTECT_HEAD:
875231200Smm    case SIGN_HEAD:
876231200Smm      flags = archive_le16dec(p + 3);
877231200Smm      skip = archive_le16dec(p + 5);
878231200Smm      if (skip < 7) {
879231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
880231200Smm          "Invalid header size");
881231200Smm        return (ARCHIVE_FATAL);
882231200Smm      }
883231200Smm      if (skip > 7) {
884231200Smm        if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
885231200Smm          return (ARCHIVE_FATAL);
886231200Smm        p = h;
887231200Smm      }
888231200Smm      if (flags & HD_ADD_SIZE_PRESENT)
889231200Smm      {
890231200Smm        if (skip < 7 + 4) {
891231200Smm          archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
892231200Smm            "Invalid header size");
893231200Smm          return (ARCHIVE_FATAL);
894231200Smm        }
895231200Smm        skip += archive_le32dec(p + 7);
896231200Smm        if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
897231200Smm          return (ARCHIVE_FATAL);
898231200Smm        p = h;
899231200Smm      }
900231200Smm
901231200Smm      crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2);
902231200Smm      if ((crc32_val & 0xffff) != archive_le16dec(p)) {
903231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
904231200Smm          "Header CRC error");
905231200Smm        return (ARCHIVE_FATAL);
906231200Smm      }
907231200Smm      __archive_read_consume(a, skip);
908231200Smm      break;
909231200Smm
910231200Smm    case NEWSUB_HEAD:
911231200Smm      if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN)
912231200Smm        return ret;
913231200Smm      break;
914231200Smm
915231200Smm    case ENDARC_HEAD:
916231200Smm      return (ARCHIVE_EOF);
917231200Smm
918231200Smm    default:
919231200Smm      archive_set_error(&a->archive,  ARCHIVE_ERRNO_FILE_FORMAT,
920231200Smm                        "Bad RAR file");
921231200Smm      return (ARCHIVE_FATAL);
922231200Smm    }
923231200Smm  }
924231200Smm}
925231200Smm
926231200Smmstatic int
927231200Smmarchive_read_format_rar_read_data(struct archive_read *a, const void **buff,
928231200Smm                                  size_t *size, int64_t *offset)
929231200Smm{
930231200Smm  struct rar *rar = (struct rar *)(a->format->data);
931231200Smm  int ret;
932231200Smm
933231200Smm  if (rar->bytes_unconsumed > 0) {
934231200Smm      /* Consume as much as the decompressor actually used. */
935231200Smm      __archive_read_consume(a, rar->bytes_unconsumed);
936231200Smm      rar->bytes_unconsumed = 0;
937231200Smm  }
938231200Smm
939231200Smm  if (rar->entry_eof) {
940231200Smm    *buff = NULL;
941231200Smm    *size = 0;
942231200Smm    *offset = rar->offset;
943231200Smm    return (ARCHIVE_EOF);
944231200Smm  }
945231200Smm
946231200Smm  switch (rar->compression_method)
947231200Smm  {
948231200Smm  case COMPRESS_METHOD_STORE:
949231200Smm    ret = read_data_stored(a, buff, size, offset);
950231200Smm    break;
951231200Smm
952231200Smm  case COMPRESS_METHOD_FASTEST:
953231200Smm  case COMPRESS_METHOD_FAST:
954231200Smm  case COMPRESS_METHOD_NORMAL:
955231200Smm  case COMPRESS_METHOD_GOOD:
956231200Smm  case COMPRESS_METHOD_BEST:
957231200Smm    ret = read_data_compressed(a, buff, size, offset);
958231200Smm    if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
959231200Smm      __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
960231200Smm    break;
961231200Smm
962231200Smm  default:
963231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
964231200Smm                      "Unsupported compression method for RAR file.");
965231200Smm    ret = ARCHIVE_FATAL;
966231200Smm    break;
967231200Smm  }
968231200Smm  return (ret);
969231200Smm}
970231200Smm
971231200Smmstatic int
972231200Smmarchive_read_format_rar_read_data_skip(struct archive_read *a)
973231200Smm{
974231200Smm  struct rar *rar;
975231200Smm  int64_t bytes_skipped;
976231200Smm
977231200Smm  rar = (struct rar *)(a->format->data);
978231200Smm
979231200Smm  if (rar->bytes_unconsumed > 0) {
980231200Smm      /* Consume as much as the decompressor actually used. */
981231200Smm      __archive_read_consume(a, rar->bytes_unconsumed);
982231200Smm      rar->bytes_unconsumed = 0;
983231200Smm  }
984231200Smm
985231200Smm  if (rar->bytes_remaining > 0) {
986231200Smm    bytes_skipped = __archive_read_consume(a, rar->bytes_remaining);
987231200Smm    if (bytes_skipped < 0)
988231200Smm      return (ARCHIVE_FATAL);
989231200Smm  }
990231200Smm  return (ARCHIVE_OK);
991231200Smm}
992231200Smm
993231200Smmstatic int
994231200Smmarchive_read_format_rar_cleanup(struct archive_read *a)
995231200Smm{
996231200Smm  struct rar *rar;
997231200Smm
998231200Smm  rar = (struct rar *)(a->format->data);
999231200Smm  free_codes(a);
1000231200Smm  free(rar->filename);
1001231200Smm  free(rar->unp_buffer);
1002231200Smm  free(rar->lzss.window);
1003231200Smm  __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
1004231200Smm  free(rar);
1005231200Smm  (a->format->data) = NULL;
1006231200Smm  return (ARCHIVE_OK);
1007231200Smm}
1008231200Smm
1009231200Smmstatic int
1010231200Smmread_header(struct archive_read *a, struct archive_entry *entry,
1011231200Smm            char head_type)
1012231200Smm{
1013231200Smm  const void *h;
1014231200Smm  const char *p, *endp;
1015231200Smm  struct rar *rar;
1016231200Smm  struct rar_header rar_header;
1017231200Smm  struct rar_file_header file_header;
1018231200Smm  int64_t header_size;
1019231200Smm  unsigned filename_size, end;
1020231200Smm  char *filename;
1021231200Smm  char *strp;
1022231200Smm  char packed_size[8];
1023231200Smm  char unp_size[8];
1024231200Smm  int time;
1025231200Smm  struct archive_string_conv *sconv, *fn_sconv;
1026231200Smm  unsigned long crc32_val;
1027231200Smm  int ret = (ARCHIVE_OK), ret2;
1028231200Smm
1029231200Smm  rar = (struct rar *)(a->format->data);
1030231200Smm
1031231200Smm  /* Setup a string conversion object for non-rar-unicode filenames. */
1032231200Smm  sconv = rar->opt_sconv;
1033231200Smm  if (sconv == NULL) {
1034231200Smm    if (!rar->init_default_conversion) {
1035231200Smm      rar->sconv_default =
1036231200Smm          archive_string_default_conversion_for_read(
1037231200Smm            &(a->archive));
1038231200Smm      rar->init_default_conversion = 1;
1039231200Smm    }
1040231200Smm    sconv = rar->sconv_default;
1041231200Smm  }
1042231200Smm
1043231200Smm
1044231200Smm  if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
1045231200Smm    return (ARCHIVE_FATAL);
1046231200Smm  p = h;
1047231200Smm  memcpy(&rar_header, p, sizeof(rar_header));
1048231200Smm  rar->file_flags = archive_le16dec(rar_header.flags);
1049231200Smm  header_size = archive_le16dec(rar_header.size);
1050231200Smm  if (header_size < sizeof(file_header) + 7) {
1051231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1052231200Smm      "Invalid header size");
1053231200Smm    return (ARCHIVE_FATAL);
1054231200Smm  }
1055231200Smm  crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2);
1056231200Smm  __archive_read_consume(a, 7);
1057231200Smm
1058231200Smm  if (!(rar->file_flags & FHD_SOLID))
1059231200Smm  {
1060231200Smm    rar->compression_method = 0;
1061231200Smm    rar->packed_size = 0;
1062231200Smm    rar->unp_size = 0;
1063231200Smm    rar->mtime = 0;
1064231200Smm    rar->ctime = 0;
1065231200Smm    rar->atime = 0;
1066231200Smm    rar->arctime = 0;
1067231200Smm    rar->mode = 0;
1068231200Smm    memset(&rar->salt, 0, sizeof(rar->salt));
1069231200Smm    rar->atime = 0;
1070231200Smm    rar->ansec = 0;
1071231200Smm    rar->ctime = 0;
1072231200Smm    rar->cnsec = 0;
1073231200Smm    rar->mtime = 0;
1074231200Smm    rar->mnsec = 0;
1075231200Smm    rar->arctime = 0;
1076231200Smm    rar->arcnsec = 0;
1077231200Smm  }
1078231200Smm  else
1079231200Smm  {
1080231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1081231200Smm                      "RAR solid archive support unavailable.");
1082231200Smm    return (ARCHIVE_FATAL);
1083231200Smm  }
1084231200Smm
1085231200Smm  if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL)
1086231200Smm    return (ARCHIVE_FATAL);
1087231200Smm
1088231200Smm  /* File Header CRC check. */
1089231200Smm  crc32_val = crc32(crc32_val, h, header_size - 7);
1090231200Smm  if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) {
1091231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1092231200Smm      "Header CRC error");
1093231200Smm    return (ARCHIVE_FATAL);
1094231200Smm  }
1095231200Smm  /* If no CRC error, Go on parsing File Header. */
1096231200Smm  p = h;
1097231200Smm  endp = p + header_size - 7;
1098231200Smm  memcpy(&file_header, p, sizeof(file_header));
1099231200Smm  p += sizeof(file_header);
1100231200Smm
1101231200Smm  rar->compression_method = file_header.method;
1102231200Smm
1103231200Smm  time = archive_le32dec(file_header.file_time);
1104231200Smm  rar->mtime = get_time(time);
1105231200Smm
1106231200Smm  rar->file_crc = archive_le32dec(file_header.file_crc);
1107231200Smm
1108231200Smm  if (rar->file_flags & FHD_PASSWORD)
1109231200Smm  {
1110231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1111231200Smm                      "RAR encryption support unavailable.");
1112231200Smm    return (ARCHIVE_FATAL);
1113231200Smm  }
1114231200Smm
1115231200Smm  if (rar->file_flags & FHD_LARGE)
1116231200Smm  {
1117231200Smm    memcpy(packed_size, file_header.pack_size, 4);
1118231200Smm    memcpy(packed_size + 4, p, 4); /* High pack size */
1119231200Smm    p += 4;
1120231200Smm    memcpy(unp_size, file_header.unp_size, 4);
1121231200Smm    memcpy(unp_size + 4, p, 4); /* High unpack size */
1122231200Smm    p += 4;
1123231200Smm    rar->packed_size = archive_le64dec(&packed_size);
1124231200Smm    rar->unp_size = archive_le64dec(&unp_size);
1125231200Smm  }
1126231200Smm  else
1127231200Smm  {
1128231200Smm    rar->packed_size = archive_le32dec(file_header.pack_size);
1129231200Smm    rar->unp_size = archive_le32dec(file_header.unp_size);
1130231200Smm  }
1131231200Smm
1132231200Smm  /* TODO: Need to use CRC check for these kind of cases.
1133231200Smm   * For now, check if sizes are not < 0.
1134231200Smm   */
1135231200Smm  if (rar->packed_size < 0 || rar->unp_size < 0)
1136231200Smm  {
1137231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1138231200Smm                      "Invalid sizes specified.");
1139231200Smm    return (ARCHIVE_FATAL);
1140231200Smm  }
1141231200Smm
1142231200Smm  /* TODO: RARv3 subblocks contain comments. For now the complete block is
1143231200Smm   * consumed at the end.
1144231200Smm   */
1145231200Smm  if (head_type == NEWSUB_HEAD) {
1146231200Smm    size_t distance = p - (const char *)h;
1147231200Smm    header_size += rar->packed_size;
1148231200Smm    /* Make sure we have the extended data. */
1149231200Smm    if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL)
1150231200Smm        return (ARCHIVE_FATAL);
1151231200Smm    p = h;
1152231200Smm    endp = p + header_size - 7;
1153231200Smm    p += distance;
1154231200Smm  }
1155231200Smm
1156231200Smm  filename_size = archive_le16dec(file_header.name_size);
1157231200Smm  if (p + filename_size > endp) {
1158231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1159231200Smm      "Invalid filename size");
1160231200Smm    return (ARCHIVE_FATAL);
1161231200Smm  }
1162231200Smm  if (rar->filename_allocated < filename_size+2) {
1163231200Smm    rar->filename = realloc(rar->filename, filename_size+2);
1164231200Smm    if (rar->filename == NULL) {
1165231200Smm      archive_set_error(&a->archive, ENOMEM,
1166231200Smm                        "Couldn't allocate memory.");
1167231200Smm      return (ARCHIVE_FATAL);
1168231200Smm    }
1169231200Smm  }
1170231200Smm  filename = rar->filename;
1171231200Smm  memcpy(filename, p, filename_size);
1172231200Smm  filename[filename_size] = '\0';
1173231200Smm  if (rar->file_flags & FHD_UNICODE)
1174231200Smm  {
1175231200Smm    if (filename_size != strlen(filename))
1176231200Smm    {
1177231200Smm      unsigned char highbyte, flagbits, flagbyte, length, offset;
1178231200Smm
1179231200Smm      end = filename_size;
1180231200Smm      filename_size = 0;
1181231200Smm      offset = strlen(filename) + 1;
1182231200Smm      highbyte = *(p + offset++);
1183231200Smm      flagbits = 0;
1184231200Smm      flagbyte = 0;
1185231200Smm      while (offset < end && filename_size < end)
1186231200Smm      {
1187231200Smm        if (!flagbits)
1188231200Smm        {
1189231200Smm          flagbyte = *(p + offset++);
1190231200Smm          flagbits = 8;
1191231200Smm        }
1192231200Smm
1193231200Smm        flagbits -= 2;
1194231200Smm        switch((flagbyte >> flagbits) & 3)
1195231200Smm        {
1196231200Smm          case 0:
1197231200Smm            filename[filename_size++] = '\0';
1198231200Smm            filename[filename_size++] = *(p + offset++);
1199231200Smm            break;
1200231200Smm          case 1:
1201231200Smm            filename[filename_size++] = highbyte;
1202231200Smm            filename[filename_size++] = *(p + offset++);
1203231200Smm            break;
1204231200Smm          case 2:
1205231200Smm            filename[filename_size++] = *(p + offset + 1);
1206231200Smm            filename[filename_size++] = *(p + offset);
1207231200Smm            offset += 2;
1208231200Smm            break;
1209231200Smm          case 3:
1210231200Smm          {
1211231200Smm            length = *(p + offset++);
1212231200Smm            while (length)
1213231200Smm            {
1214231200Smm	          if (filename_size >= end)
1215231200Smm			    break;
1216231200Smm              filename[filename_size++] = *(p + offset);
1217231200Smm              length--;
1218231200Smm            }
1219231200Smm          }
1220231200Smm          break;
1221231200Smm        }
1222231200Smm      }
1223231200Smm      if (filename_size >= end) {
1224231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1225231200Smm          "Invalid filename");
1226231200Smm        return (ARCHIVE_FATAL);
1227231200Smm      }
1228231200Smm      filename[filename_size++] = '\0';
1229231200Smm      filename[filename_size++] = '\0';
1230231200Smm
1231231200Smm      /* Decoded unicode form is UTF-16BE, so we have to update a string
1232231200Smm       * conversion object for it. */
1233231200Smm      if (rar->sconv_utf16be == NULL) {
1234231200Smm        rar->sconv_utf16be = archive_string_conversion_from_charset(
1235231200Smm           &a->archive, "UTF-16BE", 1);
1236231200Smm        if (rar->sconv_utf16be == NULL)
1237231200Smm          return (ARCHIVE_FATAL);
1238231200Smm      }
1239231200Smm      fn_sconv = rar->sconv_utf16be;
1240231200Smm
1241231200Smm      strp = filename;
1242231200Smm      while (memcmp(strp, "\x00\x00", 2))
1243231200Smm      {
1244231200Smm        if (!memcmp(strp, "\x00\\", 2))
1245231200Smm          *(strp + 1) = '/';
1246231200Smm        strp += 2;
1247231200Smm      }
1248231200Smm      p += offset;
1249231200Smm    } else {
1250231200Smm      /*
1251231200Smm       * If FHD_UNICODE is set but no unicode data, this file name form
1252231200Smm       * is UTF-8, so we have to update a string conversion object for
1253231200Smm       * it accordingly.
1254231200Smm       */
1255231200Smm      if (rar->sconv_utf8 == NULL) {
1256231200Smm        rar->sconv_utf8 = archive_string_conversion_from_charset(
1257231200Smm           &a->archive, "UTF-8", 1);
1258231200Smm        if (rar->sconv_utf8 == NULL)
1259231200Smm          return (ARCHIVE_FATAL);
1260231200Smm      }
1261231200Smm      fn_sconv = rar->sconv_utf8;
1262231200Smm      while ((strp = strchr(filename, '\\')) != NULL)
1263231200Smm        *strp = '/';
1264231200Smm      p += filename_size;
1265231200Smm    }
1266231200Smm  }
1267231200Smm  else
1268231200Smm  {
1269231200Smm    fn_sconv = sconv;
1270231200Smm    while ((strp = strchr(filename, '\\')) != NULL)
1271231200Smm      *strp = '/';
1272231200Smm    p += filename_size;
1273231200Smm  }
1274231200Smm
1275231200Smm  if (rar->file_flags & FHD_SALT)
1276231200Smm  {
1277231200Smm    if (p + 8 > endp) {
1278231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1279231200Smm        "Invalid header size");
1280231200Smm      return (ARCHIVE_FATAL);
1281231200Smm    }
1282231200Smm    memcpy(rar->salt, p, 8);
1283231200Smm    p += 8;
1284231200Smm  }
1285231200Smm
1286231200Smm  if (rar->file_flags & FHD_EXTTIME) {
1287231200Smm    if (read_exttime(p, rar, endp) < 0) {
1288231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1289231200Smm        "Invalid header size");
1290231200Smm      return (ARCHIVE_FATAL);
1291231200Smm    }
1292231200Smm  }
1293231200Smm
1294231200Smm  __archive_read_consume(a, header_size - 7);
1295231200Smm
1296231200Smm  switch(file_header.host_os)
1297231200Smm  {
1298231200Smm  case OS_MSDOS:
1299231200Smm  case OS_OS2:
1300231200Smm  case OS_WIN32:
1301231200Smm    rar->mode = archive_le32dec(file_header.file_attr);
1302231200Smm    if (rar->mode & FILE_ATTRIBUTE_DIRECTORY)
1303231200Smm      rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
1304231200Smm    else
1305231200Smm      rar->mode = AE_IFREG;
1306231200Smm    rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1307231200Smm    break;
1308231200Smm
1309231200Smm  case OS_UNIX:
1310231200Smm  case OS_MAC_OS:
1311231200Smm  case OS_BEOS:
1312231200Smm    rar->mode = archive_le32dec(file_header.file_attr);
1313231200Smm    break;
1314231200Smm
1315231200Smm  default:
1316231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1317231200Smm                      "Unknown file attributes from RAR file's host OS");
1318231200Smm    return (ARCHIVE_FATAL);
1319231200Smm  }
1320231200Smm
1321231200Smm  rar->bytes_remaining = rar->packed_size;
1322231200Smm  rar->bytes_uncopied = rar->bytes_unconsumed = 0;
1323231200Smm  rar->lzss.position = rar->dictionary_size = rar->offset = 0;
1324231200Smm  rar->offset_outgoing = 0;
1325231200Smm  rar->br.cache_avail = 0;
1326231200Smm  rar->br.avail_in = 0;
1327231200Smm  rar->crc_calculated = 0;
1328231200Smm  rar->entry_eof = 0;
1329231200Smm  rar->valid = 1;
1330231200Smm  rar->is_ppmd_block = 0;
1331231200Smm  rar->start_new_table = 1;
1332231200Smm  free(rar->unp_buffer);
1333231200Smm  rar->unp_buffer = NULL;
1334231200Smm  rar->unp_offset = 0;
1335231200Smm  rar->unp_buffer_size = UNP_BUFFER_SIZE;
1336231200Smm  memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
1337231200Smm  __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
1338231200Smm  rar->ppmd_valid = rar->ppmd_eod = 0;
1339231200Smm
1340231200Smm  /* Don't set any archive entries for non-file header types */
1341231200Smm  if (head_type == NEWSUB_HEAD)
1342231200Smm    return ret;
1343231200Smm
1344231200Smm  archive_entry_set_mtime(entry, rar->mtime, rar->mnsec);
1345231200Smm  archive_entry_set_ctime(entry, rar->ctime, rar->cnsec);
1346231200Smm  archive_entry_set_atime(entry, rar->atime, rar->ansec);
1347231200Smm  archive_entry_set_size(entry, rar->unp_size);
1348231200Smm  archive_entry_set_mode(entry, rar->mode);
1349231200Smm
1350231200Smm  if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv))
1351231200Smm  {
1352231200Smm    if (errno == ENOMEM)
1353231200Smm    {
1354231200Smm      archive_set_error(&a->archive, ENOMEM,
1355231200Smm                        "Can't allocate memory for Pathname");
1356231200Smm      return (ARCHIVE_FATAL);
1357231200Smm    }
1358231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1359231200Smm                      "Pathname cannot be converted from %s to current locale.",
1360231200Smm                      archive_string_conversion_charset_name(fn_sconv));
1361231200Smm    ret = (ARCHIVE_WARN);
1362231200Smm  }
1363231200Smm
1364231200Smm  if (((rar->mode) & AE_IFMT) == AE_IFLNK)
1365231200Smm  {
1366231200Smm    /* Make sure a symbolic-link file does not have its body. */
1367231200Smm    rar->bytes_remaining = 0;
1368231200Smm    archive_entry_set_size(entry, 0);
1369231200Smm
1370231200Smm    /* Read a symbolic-link name. */
1371231200Smm    if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN))
1372231200Smm      return ret2;
1373231200Smm    if (ret > ret2)
1374231200Smm      ret = ret2;
1375231200Smm  }
1376231200Smm
1377231200Smm  if (rar->bytes_remaining == 0)
1378231200Smm    rar->entry_eof = 1;
1379231200Smm
1380231200Smm  return ret;
1381231200Smm}
1382231200Smm
1383231200Smmstatic time_t
1384231200Smmget_time(int time)
1385231200Smm{
1386231200Smm  struct tm tm;
1387231200Smm  tm.tm_sec = 2 * (time & 0x1f);
1388231200Smm  tm.tm_min = (time >> 5) & 0x3f;
1389231200Smm  tm.tm_hour = (time >> 11) & 0x1f;
1390231200Smm  tm.tm_mday = (time >> 16) & 0x1f;
1391231200Smm  tm.tm_mon = ((time >> 21) & 0x0f) - 1;
1392231200Smm  tm.tm_year = ((time >> 25) & 0x7f) + 80;
1393231200Smm  tm.tm_isdst = -1;
1394231200Smm  return mktime(&tm);
1395231200Smm}
1396231200Smm
1397231200Smmstatic int
1398231200Smmread_exttime(const char *p, struct rar *rar, const char *endp)
1399231200Smm{
1400231200Smm  unsigned rmode, flags, rem, j, count;
1401231200Smm  int time, i;
1402231200Smm  struct tm *tm;
1403231200Smm  time_t t;
1404231200Smm  long nsec;
1405231200Smm
1406231200Smm  if (p + 2 > endp)
1407231200Smm    return (-1);
1408231200Smm  flags = archive_le16dec(p);
1409231200Smm  p += 2;
1410231200Smm
1411231200Smm  for (i = 3; i >= 0; i--)
1412231200Smm  {
1413231200Smm    t = 0;
1414231200Smm    if (i == 3)
1415231200Smm      t = rar->mtime;
1416231200Smm    rmode = flags >> i * 4;
1417231200Smm    if (rmode & 8)
1418231200Smm    {
1419231200Smm      if (!t)
1420231200Smm      {
1421231200Smm        if (p + 4 > endp)
1422231200Smm          return (-1);
1423231200Smm        time = archive_le32dec(p);
1424231200Smm        t = get_time(time);
1425231200Smm        p += 4;
1426231200Smm      }
1427231200Smm      rem = 0;
1428231200Smm      count = rmode & 3;
1429231200Smm      if (p + count > endp)
1430231200Smm        return (-1);
1431231200Smm      for (j = 0; j < count; j++)
1432231200Smm      {
1433231200Smm        rem = ((*p) << 16) | (rem >> 8);
1434231200Smm        p++;
1435231200Smm      }
1436231200Smm      tm = localtime(&t);
1437231200Smm      nsec = tm->tm_sec + rem / NS_UNIT;
1438231200Smm      if (rmode & 4)
1439231200Smm      {
1440231200Smm        tm->tm_sec++;
1441231200Smm        t = mktime(tm);
1442231200Smm      }
1443231200Smm      if (i == 3)
1444231200Smm      {
1445231200Smm        rar->mtime = t;
1446231200Smm        rar->mnsec = nsec;
1447231200Smm      }
1448231200Smm      else if (i == 2)
1449231200Smm      {
1450231200Smm        rar->ctime = t;
1451231200Smm        rar->cnsec = nsec;
1452231200Smm      }
1453231200Smm      else if (i == 1)
1454231200Smm      {
1455231200Smm        rar->atime = t;
1456231200Smm        rar->ansec = nsec;
1457231200Smm      }
1458231200Smm      else
1459231200Smm      {
1460231200Smm        rar->arctime = t;
1461231200Smm        rar->arcnsec = nsec;
1462231200Smm      }
1463231200Smm    }
1464231200Smm  }
1465231200Smm  return (0);
1466231200Smm}
1467231200Smm
1468231200Smmstatic int
1469231200Smmread_symlink_stored(struct archive_read *a, struct archive_entry *entry,
1470231200Smm                    struct archive_string_conv *sconv)
1471231200Smm{
1472231200Smm  const void *h;
1473231200Smm  const char *p;
1474231200Smm  struct rar *rar;
1475231200Smm  int ret = (ARCHIVE_OK);
1476231200Smm
1477231200Smm  rar = (struct rar *)(a->format->data);
1478231200Smm  if ((h = __archive_read_ahead(a, rar->packed_size, NULL)) == NULL)
1479231200Smm    return (ARCHIVE_FATAL);
1480231200Smm  p = h;
1481231200Smm
1482231200Smm  if (archive_entry_copy_symlink_l(entry, p, rar->packed_size, sconv))
1483231200Smm  {
1484231200Smm    if (errno == ENOMEM)
1485231200Smm    {
1486231200Smm      archive_set_error(&a->archive, ENOMEM,
1487231200Smm                        "Can't allocate memory for link");
1488231200Smm      return (ARCHIVE_FATAL);
1489231200Smm    }
1490231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1491231200Smm                      "link cannot be converted from %s to current locale.",
1492231200Smm                      archive_string_conversion_charset_name(sconv));
1493231200Smm    ret = (ARCHIVE_WARN);
1494231200Smm  }
1495231200Smm  __archive_read_consume(a, rar->packed_size);
1496231200Smm  return ret;
1497231200Smm}
1498231200Smm
1499231200Smmstatic int
1500231200Smmread_data_stored(struct archive_read *a, const void **buff, size_t *size,
1501231200Smm                 int64_t *offset)
1502231200Smm{
1503231200Smm  struct rar *rar;
1504231200Smm  ssize_t bytes_avail;
1505231200Smm
1506231200Smm  rar = (struct rar *)(a->format->data);
1507231200Smm  if (rar->bytes_remaining == 0)
1508231200Smm  {
1509231200Smm    *buff = NULL;
1510231200Smm    *size = 0;
1511231200Smm    *offset = rar->offset;
1512231200Smm    if (rar->file_crc != rar->crc_calculated) {
1513231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1514231200Smm                        "File CRC error");
1515231200Smm      return (ARCHIVE_FATAL);
1516231200Smm    }
1517231200Smm    rar->entry_eof = 1;
1518231200Smm    return (ARCHIVE_EOF);
1519231200Smm  }
1520231200Smm
1521231200Smm  *buff = __archive_read_ahead(a, 1, &bytes_avail);
1522231200Smm  if (bytes_avail <= 0)
1523231200Smm  {
1524231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1525231200Smm                      "Truncated RAR file data");
1526231200Smm    return (ARCHIVE_FATAL);
1527231200Smm  }
1528231200Smm  if (bytes_avail > rar->bytes_remaining)
1529231200Smm    bytes_avail = rar->bytes_remaining;
1530231200Smm
1531231200Smm  *size = bytes_avail;
1532231200Smm  *offset = rar->offset;
1533231200Smm  rar->offset += bytes_avail;
1534231200Smm  rar->bytes_remaining -= bytes_avail;
1535231200Smm  rar->bytes_unconsumed = bytes_avail;
1536231200Smm  /* Calculate File CRC. */
1537231200Smm  rar->crc_calculated = crc32(rar->crc_calculated, *buff, bytes_avail);
1538231200Smm  return (ARCHIVE_OK);
1539231200Smm}
1540231200Smm
1541231200Smmstatic int
1542231200Smmread_data_compressed(struct archive_read *a, const void **buff, size_t *size,
1543231200Smm               int64_t *offset)
1544231200Smm{
1545231200Smm  struct rar *rar;
1546231200Smm  int64_t start, end, actualend;
1547231200Smm  size_t bs;
1548231200Smm  int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i;
1549231200Smm
1550231200Smm  rar = (struct rar *)(a->format->data);
1551231200Smm
1552231200Smm  do {
1553231200Smm    if (!rar->valid)
1554231200Smm      return (ARCHIVE_FATAL);
1555231200Smm    if (rar->ppmd_eod ||
1556231200Smm       (rar->dictionary_size && rar->offset >= rar->unp_size))
1557231200Smm    {
1558231200Smm      if (rar->unp_offset > 0) {
1559231200Smm        /*
1560231200Smm         * We have unprocessed extracted data. write it out.
1561231200Smm         */
1562231200Smm        *buff = rar->unp_buffer;
1563231200Smm        *size = rar->unp_offset;
1564231200Smm        *offset = rar->offset_outgoing;
1565231200Smm        rar->offset_outgoing += *size;
1566231200Smm        /* Calculate File CRC. */
1567231200Smm        rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
1568231200Smm        rar->unp_offset = 0;
1569231200Smm        return (ARCHIVE_OK);
1570231200Smm      }
1571231200Smm      *buff = NULL;
1572231200Smm      *size = 0;
1573231200Smm      *offset = rar->offset;
1574231200Smm      if (rar->file_crc != rar->crc_calculated) {
1575231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1576231200Smm                          "File CRC error");
1577231200Smm        return (ARCHIVE_FATAL);
1578231200Smm      }
1579231200Smm      rar->entry_eof = 1;
1580231200Smm      return (ARCHIVE_EOF);
1581231200Smm    }
1582231200Smm
1583231200Smm    if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0)
1584231200Smm    {
1585231200Smm      if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
1586231200Smm        bs = rar->unp_buffer_size - rar->unp_offset;
1587231200Smm      else
1588231200Smm        bs = rar->bytes_uncopied;
1589231200Smm      ret = copy_from_lzss_window(a, buff, rar->offset, bs);
1590231200Smm      if (ret != ARCHIVE_OK)
1591231200Smm        return (ret);
1592231200Smm      rar->offset += bs;
1593231200Smm      rar->bytes_uncopied -= bs;
1594231200Smm      if (*buff != NULL) {
1595231200Smm        rar->unp_offset = 0;
1596231200Smm        *size = rar->unp_buffer_size;
1597231200Smm        *offset = rar->offset_outgoing;
1598231200Smm        rar->offset_outgoing += *size;
1599231200Smm        /* Calculate File CRC. */
1600231200Smm        rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
1601231200Smm        return (ret);
1602231200Smm      }
1603231200Smm      continue;
1604231200Smm    }
1605231200Smm
1606231200Smm    if (!rar->br.next_in &&
1607231200Smm      (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN)
1608231200Smm      return (ret);
1609231200Smm    if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN)))
1610231200Smm      return (ret);
1611231200Smm
1612231200Smm    if (rar->is_ppmd_block)
1613231200Smm    {
1614231200Smm      if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1615231200Smm        &rar->ppmd7_context, &rar->range_dec.p)) < 0)
1616231200Smm      {
1617231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1618231200Smm                          "Invalid symbol");
1619231200Smm        return (ARCHIVE_FATAL);
1620231200Smm      }
1621231200Smm      if(sym != rar->ppmd_escape)
1622231200Smm      {
1623231200Smm        lzss_emit_literal(rar, sym);
1624231200Smm        rar->bytes_uncopied++;
1625231200Smm      }
1626231200Smm      else
1627231200Smm      {
1628231200Smm        if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1629231200Smm          &rar->ppmd7_context, &rar->range_dec.p)) < 0)
1630231200Smm        {
1631231200Smm          archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1632231200Smm                            "Invalid symbol");
1633231200Smm          return (ARCHIVE_FATAL);
1634231200Smm        }
1635231200Smm
1636231200Smm        switch(code)
1637231200Smm        {
1638231200Smm          case 0:
1639231200Smm            rar->start_new_table = 1;
1640231200Smm            return read_data_compressed(a, buff, size, offset);
1641231200Smm
1642231200Smm          case 2:
1643231200Smm            rar->ppmd_eod = 1;/* End Of ppmd Data. */
1644231200Smm            continue;
1645231200Smm
1646231200Smm          case 3:
1647231200Smm            archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1648231200Smm                              "Parsing filters is unsupported.");
1649231200Smm            return (ARCHIVE_FAILED);
1650231200Smm
1651231200Smm          case 4:
1652231200Smm            lzss_offset = 0;
1653231200Smm            for (i = 2; i >= 0; i--)
1654231200Smm            {
1655231200Smm              if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1656231200Smm                &rar->ppmd7_context, &rar->range_dec.p)) < 0)
1657231200Smm              {
1658231200Smm                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1659231200Smm                                  "Invalid symbol");
1660231200Smm                return (ARCHIVE_FATAL);
1661231200Smm              }
1662231200Smm              lzss_offset |= code << (i * 8);
1663231200Smm            }
1664231200Smm            if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1665231200Smm              &rar->ppmd7_context, &rar->range_dec.p)) < 0)
1666231200Smm            {
1667231200Smm              archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1668231200Smm                                "Invalid symbol");
1669231200Smm              return (ARCHIVE_FATAL);
1670231200Smm            }
1671231200Smm            lzss_emit_match(rar, lzss_offset + 2, length + 32);
1672231200Smm            rar->bytes_uncopied += length + 32;
1673231200Smm            break;
1674231200Smm
1675231200Smm          case 5:
1676231200Smm            if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1677231200Smm              &rar->ppmd7_context, &rar->range_dec.p)) < 0)
1678231200Smm            {
1679231200Smm              archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1680231200Smm                                "Invalid symbol");
1681231200Smm              return (ARCHIVE_FATAL);
1682231200Smm            }
1683231200Smm            lzss_emit_match(rar, 1, length + 4);
1684231200Smm            rar->bytes_uncopied += length + 4;
1685231200Smm            break;
1686231200Smm
1687231200Smm         default:
1688231200Smm           lzss_emit_literal(rar, sym);
1689231200Smm           rar->bytes_uncopied++;
1690231200Smm        }
1691231200Smm      }
1692231200Smm    }
1693231200Smm    else
1694231200Smm    {
1695231200Smm      start = rar->offset;
1696231200Smm      end = start + rar->dictionary_size;
1697231200Smm      rar->filterstart = INT64_MAX;
1698231200Smm
1699231200Smm      if ((actualend = expand(a, end)) < 0)
1700231200Smm        return ((int)actualend);
1701231200Smm
1702231200Smm      rar->bytes_uncopied = actualend - start;
1703231200Smm      if (rar->bytes_uncopied == 0) {
1704231200Smm          /* Broken RAR files cause this case.
1705231200Smm          * NOTE: If this case were possible on a normal RAR file
1706231200Smm          * we would find out where it was actually bad and
1707231200Smm          * what we would do to solve it. */
1708231200Smm          archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1709231200Smm                            "Internal error extracting RAR file");
1710231200Smm          return (ARCHIVE_FATAL);
1711231200Smm      }
1712231200Smm    }
1713231200Smm    if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
1714231200Smm      bs = rar->unp_buffer_size - rar->unp_offset;
1715231200Smm    else
1716231200Smm      bs = rar->bytes_uncopied;
1717231200Smm    ret = copy_from_lzss_window(a, buff, rar->offset, bs);
1718231200Smm    if (ret != ARCHIVE_OK)
1719231200Smm      return (ret);
1720231200Smm    rar->offset += bs;
1721231200Smm    rar->bytes_uncopied -= bs;
1722231200Smm    /*
1723231200Smm     * If *buff is NULL, it means unp_buffer is not full.
1724231200Smm     * So we have to continue extracting a RAR file.
1725231200Smm     */
1726231200Smm  } while (*buff == NULL);
1727231200Smm
1728231200Smm  rar->unp_offset = 0;
1729231200Smm  *size = rar->unp_buffer_size;
1730231200Smm  *offset = rar->offset_outgoing;
1731231200Smm  rar->offset_outgoing += *size;
1732231200Smm  /* Calculate File CRC. */
1733231200Smm  rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
1734231200Smm  return ret;
1735231200Smm}
1736231200Smm
1737231200Smmstatic int
1738231200Smmparse_codes(struct archive_read *a)
1739231200Smm{
1740231200Smm  int i, j, val, n, r;
1741231200Smm  unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags;
1742231200Smm  unsigned int maxorder;
1743231200Smm  struct huffman_code precode;
1744231200Smm  struct rar *rar = (struct rar *)(a->format->data);
1745231200Smm  struct rar_br *br = &(rar->br);
1746231200Smm
1747231200Smm  free_codes(a);
1748231200Smm
1749231200Smm  /* Skip to the next byte */
1750231200Smm  rar_br_consume_unalined_bits(br);
1751231200Smm
1752231200Smm  /* PPMd block flag */
1753231200Smm  if (!rar_br_read_ahead(a, br, 1))
1754231200Smm    goto truncated_data;
1755231200Smm  if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0)
1756231200Smm  {
1757231200Smm    rar_br_consume(br, 1);
1758231200Smm    if (!rar_br_read_ahead(a, br, 7))
1759231200Smm      goto truncated_data;
1760231200Smm    ppmd_flags = rar_br_bits(br, 7);
1761231200Smm    rar_br_consume(br, 7);
1762231200Smm
1763231200Smm    /* Memory is allocated in MB */
1764231200Smm    if (ppmd_flags & 0x20)
1765231200Smm    {
1766231200Smm      if (!rar_br_read_ahead(a, br, 8))
1767231200Smm        goto truncated_data;
1768231200Smm      rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20;
1769231200Smm      rar_br_consume(br, 8);
1770231200Smm    }
1771231200Smm
1772231200Smm    if (ppmd_flags & 0x40)
1773231200Smm    {
1774231200Smm      if (!rar_br_read_ahead(a, br, 8))
1775231200Smm        goto truncated_data;
1776231200Smm      rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8);
1777231200Smm      rar_br_consume(br, 8);
1778231200Smm    }
1779231200Smm    else
1780231200Smm      rar->ppmd_escape = 2;
1781231200Smm
1782231200Smm    if (ppmd_flags & 0x20)
1783231200Smm    {
1784231200Smm      maxorder = (ppmd_flags & 0x1F) + 1;
1785231200Smm      if(maxorder > 16)
1786231200Smm        maxorder = 16 + (maxorder - 16) * 3;
1787231200Smm
1788231200Smm      if (maxorder == 1)
1789231200Smm      {
1790231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1791231200Smm                          "Truncated RAR file data");
1792231200Smm        return (ARCHIVE_FATAL);
1793231200Smm      }
1794231200Smm
1795231200Smm      /* Make sure ppmd7_contest is freed before Ppmd7_Construct
1796231200Smm       * because reading a broken file cause this abnormal sequence. */
1797231200Smm      __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
1798231200Smm
1799231200Smm      rar->bytein.a = a;
1800231200Smm      rar->bytein.Read = &ppmd_read;
1801231200Smm      __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec);
1802231200Smm      rar->range_dec.Stream = &rar->bytein;
1803231200Smm      __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context);
1804231200Smm
1805231200Smm      if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context,
1806231200Smm        rar->dictionary_size, &g_szalloc))
1807231200Smm      {
1808231200Smm        archive_set_error(&a->archive, ENOMEM,
1809231200Smm                          "Out of memory");
1810231200Smm        return (ARCHIVE_FATAL);
1811231200Smm      }
1812231200Smm      if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec))
1813231200Smm      {
1814231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1815231200Smm                          "Unable to initialize PPMd range decoder");
1816231200Smm        return (ARCHIVE_FATAL);
1817231200Smm      }
1818231200Smm      __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder);
1819231200Smm      rar->ppmd_valid = 1;
1820231200Smm    }
1821231200Smm    else
1822231200Smm    {
1823231200Smm      if (!rar->ppmd_valid) {
1824231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1825231200Smm                          "Invalid PPMd sequence");
1826231200Smm        return (ARCHIVE_FATAL);
1827231200Smm      }
1828231200Smm      if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec))
1829231200Smm      {
1830231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1831231200Smm                          "Unable to initialize PPMd range decoder");
1832231200Smm        return (ARCHIVE_FATAL);
1833231200Smm      }
1834231200Smm    }
1835231200Smm  }
1836231200Smm  else
1837231200Smm  {
1838231200Smm    rar_br_consume(br, 1);
1839231200Smm
1840231200Smm    /* Keep existing table flag */
1841231200Smm    if (!rar_br_read_ahead(a, br, 1))
1842231200Smm      goto truncated_data;
1843231200Smm    if (!rar_br_bits(br, 1))
1844231200Smm      memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
1845231200Smm    rar_br_consume(br, 1);
1846231200Smm
1847231200Smm    memset(&bitlengths, 0, sizeof(bitlengths));
1848231200Smm    for (i = 0; i < MAX_SYMBOLS;)
1849231200Smm    {
1850231200Smm      if (!rar_br_read_ahead(a, br, 4))
1851231200Smm        goto truncated_data;
1852231200Smm      bitlengths[i++] = rar_br_bits(br, 4);
1853231200Smm      rar_br_consume(br, 4);
1854231200Smm      if (bitlengths[i-1] == 0xF)
1855231200Smm      {
1856231200Smm        if (!rar_br_read_ahead(a, br, 4))
1857231200Smm          goto truncated_data;
1858231200Smm        zerocount = rar_br_bits(br, 4);
1859231200Smm        rar_br_consume(br, 4);
1860231200Smm        if (zerocount)
1861231200Smm        {
1862231200Smm          i--;
1863231200Smm          for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++)
1864231200Smm            bitlengths[i++] = 0;
1865231200Smm        }
1866231200Smm      }
1867231200Smm    }
1868231200Smm
1869231200Smm    memset(&precode, 0, sizeof(precode));
1870231200Smm    r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH);
1871231200Smm    if (r != ARCHIVE_OK) {
1872231200Smm      free(precode.tree);
1873231200Smm      free(precode.table);
1874231200Smm      return (r);
1875231200Smm    }
1876231200Smm
1877231200Smm    for (i = 0; i < HUFFMAN_TABLE_SIZE;)
1878231200Smm    {
1879231200Smm      if ((val = read_next_symbol(a, &precode)) < 0) {
1880231200Smm        free(precode.tree);
1881231200Smm        free(precode.table);
1882231200Smm        return (ARCHIVE_FATAL);
1883231200Smm      }
1884231200Smm      if (val < 16)
1885231200Smm      {
1886231200Smm        rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF;
1887231200Smm        i++;
1888231200Smm      }
1889231200Smm      else if (val < 18)
1890231200Smm      {
1891231200Smm        if (i == 0)
1892231200Smm        {
1893231200Smm          free(precode.tree);
1894231200Smm          free(precode.table);
1895231200Smm          archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1896231200Smm                            "Internal error extracting RAR file.");
1897231200Smm          return (ARCHIVE_FATAL);
1898231200Smm        }
1899231200Smm
1900231200Smm        if(val == 16) {
1901231200Smm          if (!rar_br_read_ahead(a, br, 3)) {
1902231200Smm            free(precode.tree);
1903231200Smm            free(precode.table);
1904231200Smm            goto truncated_data;
1905231200Smm          }
1906231200Smm          n = rar_br_bits(br, 3) + 3;
1907231200Smm          rar_br_consume(br, 3);
1908231200Smm        } else {
1909231200Smm          if (!rar_br_read_ahead(a, br, 7)) {
1910231200Smm            free(precode.tree);
1911231200Smm            free(precode.table);
1912231200Smm            goto truncated_data;
1913231200Smm          }
1914231200Smm          n = rar_br_bits(br, 7) + 11;
1915231200Smm          rar_br_consume(br, 7);
1916231200Smm        }
1917231200Smm
1918231200Smm        for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++)
1919231200Smm        {
1920231200Smm          rar->lengthtable[i] = rar->lengthtable[i-1];
1921231200Smm          i++;
1922231200Smm        }
1923231200Smm      }
1924231200Smm      else
1925231200Smm      {
1926231200Smm        if(val == 18) {
1927231200Smm          if (!rar_br_read_ahead(a, br, 3)) {
1928231200Smm            free(precode.tree);
1929231200Smm            free(precode.table);
1930231200Smm            goto truncated_data;
1931231200Smm          }
1932231200Smm          n = rar_br_bits(br, 3) + 3;
1933231200Smm          rar_br_consume(br, 3);
1934231200Smm        } else {
1935231200Smm          if (!rar_br_read_ahead(a, br, 7)) {
1936231200Smm            free(precode.tree);
1937231200Smm            free(precode.table);
1938231200Smm            goto truncated_data;
1939231200Smm          }
1940231200Smm          n = rar_br_bits(br, 7) + 11;
1941231200Smm          rar_br_consume(br, 7);
1942231200Smm        }
1943231200Smm
1944231200Smm        for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++)
1945231200Smm          rar->lengthtable[i++] = 0;
1946231200Smm      }
1947231200Smm    }
1948231200Smm    free(precode.tree);
1949231200Smm    free(precode.table);
1950231200Smm
1951231200Smm    r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE,
1952231200Smm                MAX_SYMBOL_LENGTH);
1953231200Smm    if (r != ARCHIVE_OK)
1954231200Smm      return (r);
1955231200Smm    r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE],
1956231200Smm                OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH);
1957231200Smm    if (r != ARCHIVE_OK)
1958231200Smm      return (r);
1959231200Smm    r = create_code(a, &rar->lowoffsetcode,
1960231200Smm                &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE],
1961231200Smm                LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH);
1962231200Smm    if (r != ARCHIVE_OK)
1963231200Smm      return (r);
1964231200Smm    r = create_code(a, &rar->lengthcode,
1965231200Smm                &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE +
1966231200Smm                LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH);
1967231200Smm    if (r != ARCHIVE_OK)
1968231200Smm      return (r);
1969231200Smm  }
1970231200Smm
1971231200Smm  if (!rar->dictionary_size || !rar->lzss.window)
1972231200Smm  {
1973231200Smm    /* Seems as though dictionary sizes are not used. Even so, minimize
1974231200Smm     * memory usage as much as possible.
1975231200Smm     */
1976231200Smm    if (rar->unp_size >= DICTIONARY_MAX_SIZE)
1977231200Smm      rar->dictionary_size = DICTIONARY_MAX_SIZE;
1978231200Smm    else
1979231200Smm      rar->dictionary_size = rar_fls(rar->unp_size) << 1;
1980231200Smm    rar->lzss.window = (unsigned char *)realloc(rar->lzss.window,
1981231200Smm                                                rar->dictionary_size);
1982231200Smm    if (rar->lzss.window == NULL) {
1983231200Smm      archive_set_error(&a->archive, ENOMEM,
1984231200Smm                        "Unable to allocate memory for uncompressed data.");
1985231200Smm      return (ARCHIVE_FATAL);
1986231200Smm    }
1987231200Smm    memset(rar->lzss.window, 0, rar->dictionary_size);
1988231200Smm    rar->lzss.mask = rar->dictionary_size - 1;
1989231200Smm  }
1990231200Smm
1991231200Smm  rar->start_new_table = 0;
1992231200Smm  return (ARCHIVE_OK);
1993231200Smmtruncated_data:
1994231200Smm  archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1995231200Smm                    "Truncated RAR file data");
1996231200Smm  rar->valid = 0;
1997231200Smm  return (ARCHIVE_FATAL);
1998231200Smm}
1999231200Smm
2000231200Smmstatic void
2001231200Smmfree_codes(struct archive_read *a)
2002231200Smm{
2003231200Smm  struct rar *rar = (struct rar *)(a->format->data);
2004231200Smm  free(rar->maincode.tree);
2005231200Smm  free(rar->offsetcode.tree);
2006231200Smm  free(rar->lowoffsetcode.tree);
2007231200Smm  free(rar->lengthcode.tree);
2008231200Smm  free(rar->maincode.table);
2009231200Smm  free(rar->offsetcode.table);
2010231200Smm  free(rar->lowoffsetcode.table);
2011231200Smm  free(rar->lengthcode.table);
2012231200Smm  memset(&rar->maincode, 0, sizeof(rar->maincode));
2013231200Smm  memset(&rar->offsetcode, 0, sizeof(rar->offsetcode));
2014231200Smm  memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode));
2015231200Smm  memset(&rar->lengthcode, 0, sizeof(rar->lengthcode));
2016231200Smm}
2017231200Smm
2018231200Smm
2019231200Smmstatic int
2020231200Smmread_next_symbol(struct archive_read *a, struct huffman_code *code)
2021231200Smm{
2022231200Smm  unsigned char bit;
2023231200Smm  unsigned int bits;
2024231200Smm  int length, value, node;
2025231200Smm  struct rar *rar;
2026231200Smm  struct rar_br *br;
2027231200Smm
2028231200Smm  if (!code->table)
2029231200Smm  {
2030231200Smm    if (make_table(a, code) != (ARCHIVE_OK))
2031231200Smm      return -1;
2032231200Smm  }
2033231200Smm
2034231200Smm  rar = (struct rar *)(a->format->data);
2035231200Smm  br = &(rar->br);
2036231200Smm
2037231200Smm  /* Look ahead (peek) at bits */
2038231200Smm  if (!rar_br_read_ahead(a, br, code->tablesize)) {
2039231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2040231200Smm                      "Truncated RAR file data");
2041231200Smm    rar->valid = 0;
2042231200Smm    return -1;
2043231200Smm  }
2044231200Smm  bits = rar_br_bits(br, code->tablesize);
2045231200Smm
2046231200Smm  length = code->table[bits].length;
2047231200Smm  value = code->table[bits].value;
2048231200Smm
2049231200Smm  if (length < 0)
2050231200Smm  {
2051231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2052231200Smm                      "Invalid prefix code in bitstream");
2053231200Smm    return -1;
2054231200Smm  }
2055231200Smm
2056231200Smm  if (length <= code->tablesize)
2057231200Smm  {
2058231200Smm    /* Skip length bits */
2059231200Smm    rar_br_consume(br, length);
2060231200Smm    return value;
2061231200Smm  }
2062231200Smm
2063231200Smm  /* Skip tablesize bits */
2064231200Smm  rar_br_consume(br, code->tablesize);
2065231200Smm
2066231200Smm  node = value;
2067231200Smm  while (!(code->tree[node].branches[0] ==
2068231200Smm    code->tree[node].branches[1]))
2069231200Smm  {
2070231200Smm    if (!rar_br_read_ahead(a, br, 1)) {
2071231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2072231200Smm                        "Truncated RAR file data");
2073231200Smm      rar->valid = 0;
2074231200Smm      return -1;
2075231200Smm    }
2076231200Smm    bit = rar_br_bits(br, 1);
2077231200Smm    rar_br_consume(br, 1);
2078231200Smm
2079231200Smm    if (code->tree[node].branches[bit] < 0)
2080231200Smm    {
2081231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2082231200Smm                        "Invalid prefix code in bitstream");
2083231200Smm      return -1;
2084231200Smm    }
2085231200Smm    node = code->tree[node].branches[bit];
2086231200Smm  }
2087231200Smm
2088231200Smm  return code->tree[node].branches[0];
2089231200Smm}
2090231200Smm
2091231200Smmstatic int
2092231200Smmcreate_code(struct archive_read *a, struct huffman_code *code,
2093231200Smm            unsigned char *lengths, int numsymbols, char maxlength)
2094231200Smm{
2095231200Smm  int i, j, codebits = 0, symbolsleft = numsymbols;
2096231200Smm
2097231200Smm  if (new_node(code) < 0) {
2098231200Smm    archive_set_error(&a->archive, ENOMEM,
2099231200Smm                      "Unable to allocate memory for node data.");
2100231200Smm    return (ARCHIVE_FATAL);
2101231200Smm  }
2102231200Smm  code->numentries = 1;
2103231200Smm  code->minlength = INT_MAX;
2104231200Smm  code->maxlength = INT_MIN;
2105231200Smm  codebits = 0;
2106231200Smm  for(i = 1; i <= maxlength; i++)
2107231200Smm  {
2108231200Smm    for(j = 0; j < numsymbols; j++)
2109231200Smm    {
2110231200Smm      if (lengths[j] != i) continue;
2111231200Smm      if (add_value(a, code, j, codebits, i) != ARCHIVE_OK)
2112231200Smm        return (ARCHIVE_FATAL);
2113231200Smm      codebits++;
2114231200Smm      if (--symbolsleft <= 0) { break; break; }
2115231200Smm    }
2116231200Smm    codebits <<= 1;
2117231200Smm  }
2118231200Smm  return (ARCHIVE_OK);
2119231200Smm}
2120231200Smm
2121231200Smmstatic int
2122231200Smmadd_value(struct archive_read *a, struct huffman_code *code, int value,
2123231200Smm          int codebits, int length)
2124231200Smm{
2125231200Smm  int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode;
2126231200Smm
2127231200Smm  free(code->table);
2128231200Smm  code->table = NULL;
2129231200Smm
2130231200Smm  if(length > code->maxlength)
2131231200Smm    code->maxlength = length;
2132231200Smm  if(length < code->minlength)
2133231200Smm    code->minlength = length;
2134231200Smm
2135231200Smm  repeatpos = -1;
2136231200Smm  if (repeatpos == 0 || (repeatpos >= 0
2137231200Smm    && (((codebits >> (repeatpos - 1)) & 3) == 0
2138231200Smm    || ((codebits >> (repeatpos - 1)) & 3) == 3)))
2139231200Smm  {
2140231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2141231200Smm                      "Invalid repeat position");
2142231200Smm    return (ARCHIVE_FATAL);
2143231200Smm  }
2144231200Smm
2145231200Smm  lastnode = 0;
2146231200Smm  for (bitpos = length - 1; bitpos >= 0; bitpos--)
2147231200Smm  {
2148231200Smm    bit = (codebits >> bitpos) & 1;
2149231200Smm
2150231200Smm    /* Leaf node check */
2151231200Smm    if (code->tree[lastnode].branches[0] ==
2152231200Smm      code->tree[lastnode].branches[1])
2153231200Smm    {
2154231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2155231200Smm                        "Prefix found");
2156231200Smm      return (ARCHIVE_FATAL);
2157231200Smm    }
2158231200Smm
2159231200Smm    if (bitpos == repeatpos)
2160231200Smm    {
2161231200Smm      /* Open branch check */
2162231200Smm      if (!(code->tree[lastnode].branches[bit] < 0))
2163231200Smm      {
2164231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2165231200Smm                          "Invalid repeating code");
2166231200Smm        return (ARCHIVE_FATAL);
2167231200Smm      }
2168231200Smm
2169231200Smm      if ((repeatnode = new_node(code)) < 0) {
2170231200Smm        archive_set_error(&a->archive, ENOMEM,
2171231200Smm                          "Unable to allocate memory for node data.");
2172231200Smm        return (ARCHIVE_FATAL);
2173231200Smm      }
2174231200Smm      if ((nextnode = new_node(code)) < 0) {
2175231200Smm        archive_set_error(&a->archive, ENOMEM,
2176231200Smm                          "Unable to allocate memory for node data.");
2177231200Smm        return (ARCHIVE_FATAL);
2178231200Smm      }
2179231200Smm
2180231200Smm      /* Set branches */
2181231200Smm      code->tree[lastnode].branches[bit] = repeatnode;
2182231200Smm      code->tree[repeatnode].branches[bit] = repeatnode;
2183231200Smm      code->tree[repeatnode].branches[bit^1] = nextnode;
2184231200Smm      lastnode = nextnode;
2185231200Smm
2186231200Smm      bitpos++; /* terminating bit already handled, skip it */
2187231200Smm    }
2188231200Smm    else
2189231200Smm    {
2190231200Smm      /* Open branch check */
2191231200Smm      if (code->tree[lastnode].branches[bit] < 0)
2192231200Smm      {
2193231200Smm        if (new_node(code) < 0) {
2194231200Smm          archive_set_error(&a->archive, ENOMEM,
2195231200Smm                            "Unable to allocate memory for node data.");
2196231200Smm          return (ARCHIVE_FATAL);
2197231200Smm        }
2198231200Smm        code->tree[lastnode].branches[bit] = code->numentries++;
2199231200Smm      }
2200231200Smm
2201231200Smm      /* set to branch */
2202231200Smm      lastnode = code->tree[lastnode].branches[bit];
2203231200Smm    }
2204231200Smm  }
2205231200Smm
2206231200Smm  if (!(code->tree[lastnode].branches[0] == -1
2207231200Smm    && code->tree[lastnode].branches[1] == -2))
2208231200Smm  {
2209231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2210231200Smm                      "Prefix found");
2211231200Smm    return (ARCHIVE_FATAL);
2212231200Smm  }
2213231200Smm
2214231200Smm  /* Set leaf value */
2215231200Smm  code->tree[lastnode].branches[0] = value;
2216231200Smm  code->tree[lastnode].branches[1] = value;
2217231200Smm
2218231200Smm  return (ARCHIVE_OK);
2219231200Smm}
2220231200Smm
2221231200Smmstatic int
2222231200Smmnew_node(struct huffman_code *code)
2223231200Smm{
2224231200Smm  code->tree = (struct huffman_tree_node *)realloc(code->tree,
2225231200Smm    (code->numentries + 1) * sizeof(*code->tree));
2226231200Smm  if (code->tree == NULL)
2227231200Smm    return (-1);
2228231200Smm  code->tree[code->numentries].branches[0] = -1;
2229231200Smm  code->tree[code->numentries].branches[1] = -2;
2230231200Smm  return 1;
2231231200Smm}
2232231200Smm
2233231200Smmstatic int
2234231200Smmmake_table(struct archive_read *a, struct huffman_code *code)
2235231200Smm{
2236231200Smm  if (code->maxlength < code->minlength || code->maxlength > 10)
2237231200Smm    code->tablesize = 10;
2238231200Smm  else
2239231200Smm    code->tablesize = code->maxlength;
2240231200Smm
2241231200Smm  code->table =
2242231200Smm    (struct huffman_table_entry *)malloc(sizeof(*code->table)
2243231200Smm    * (1 << code->tablesize));
2244231200Smm
2245231200Smm  return make_table_recurse(a, code, 0, code->table, 0, code->tablesize);
2246231200Smm}
2247231200Smm
2248231200Smmstatic int
2249231200Smmmake_table_recurse(struct archive_read *a, struct huffman_code *code, int node,
2250231200Smm                   struct huffman_table_entry *table, int depth,
2251231200Smm                   int maxdepth)
2252231200Smm{
2253231200Smm  int currtablesize, i, ret = (ARCHIVE_OK);
2254231200Smm
2255231200Smm  if (!code->tree)
2256231200Smm  {
2257231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2258231200Smm                      "Huffman tree was not created.");
2259231200Smm    return (ARCHIVE_FATAL);
2260231200Smm  }
2261231200Smm  if (node < 0 || node >= code->numentries)
2262231200Smm  {
2263231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2264231200Smm                      "Invalid location to Huffman tree specified.");
2265231200Smm    return (ARCHIVE_FATAL);
2266231200Smm  }
2267231200Smm
2268231200Smm  currtablesize = 1 << (maxdepth - depth);
2269231200Smm
2270231200Smm  if (code->tree[node].branches[0] ==
2271231200Smm    code->tree[node].branches[1])
2272231200Smm  {
2273231200Smm    for(i = 0; i < currtablesize; i++)
2274231200Smm    {
2275231200Smm      table[i].length = depth;
2276231200Smm      table[i].value = code->tree[node].branches[0];
2277231200Smm    }
2278231200Smm  }
2279231200Smm  else if (node < 0)
2280231200Smm  {
2281231200Smm    for(i = 0; i < currtablesize; i++)
2282231200Smm      table[i].length = -1;
2283231200Smm  }
2284231200Smm  else
2285231200Smm  {
2286231200Smm    if(depth == maxdepth)
2287231200Smm    {
2288231200Smm      table[0].length = maxdepth + 1;
2289231200Smm      table[0].value = node;
2290231200Smm    }
2291231200Smm    else
2292231200Smm    {
2293231200Smm      ret |= make_table_recurse(a, code, code->tree[node].branches[0], table,
2294231200Smm                                depth + 1, maxdepth);
2295231200Smm      ret |= make_table_recurse(a, code, code->tree[node].branches[1],
2296231200Smm                         table + currtablesize / 2, depth + 1, maxdepth);
2297231200Smm    }
2298231200Smm  }
2299231200Smm  return ret;
2300231200Smm}
2301231200Smm
2302231200Smmstatic int64_t
2303231200Smmexpand(struct archive_read *a, int64_t end)
2304231200Smm{
2305231200Smm  static const unsigned char lengthbases[] =
2306231200Smm    {   0,   1,   2,   3,   4,   5,   6,
2307231200Smm        7,   8,  10,  12,  14,  16,  20,
2308231200Smm       24,  28,  32,  40,  48,  56,  64,
2309231200Smm       80,  96, 112, 128, 160, 192, 224 };
2310231200Smm  static const unsigned char lengthbits[] =
2311231200Smm    { 0, 0, 0, 0, 0, 0, 0,
2312231200Smm      0, 1, 1, 1, 1, 2, 2,
2313231200Smm      2, 2, 3, 3, 3, 3, 4,
2314231200Smm      4, 4, 4, 5, 5, 5, 5 };
2315231200Smm  static const unsigned int offsetbases[] =
2316231200Smm    {       0,       1,       2,       3,       4,       6,
2317231200Smm            8,      12,      16,      24,      32,      48,
2318231200Smm           64,      96,     128,     192,     256,     384,
2319231200Smm          512,     768,    1024,    1536,    2048,    3072,
2320231200Smm         4096,    6144,    8192,   12288,   16384,   24576,
2321231200Smm        32768,   49152,   65536,   98304,  131072,  196608,
2322231200Smm       262144,  327680,  393216,  458752,  524288,  589824,
2323231200Smm       655360,  720896,  786432,  851968,  917504,  983040,
2324231200Smm      1048576, 1310720, 1572864, 1835008, 2097152, 2359296,
2325231200Smm      2621440, 2883584, 3145728, 3407872, 3670016, 3932160 };
2326231200Smm  static const unsigned char offsetbits[] =
2327231200Smm    {  0,  0,  0,  0,  1,  1,  2,  2,  3,  3,  4,  4,
2328231200Smm       5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10,
2329231200Smm      11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
2330231200Smm      16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2331231200Smm      18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 };
2332231200Smm  static const unsigned char shortbases[] =
2333231200Smm    { 0, 4, 8, 16, 32, 64, 128, 192 };
2334231200Smm  static const unsigned char shortbits[] =
2335231200Smm    { 2, 2, 3, 4, 5, 6, 6, 6 };
2336231200Smm
2337231200Smm  int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol;
2338231200Smm  unsigned char newfile;
2339231200Smm  struct rar *rar = (struct rar *)(a->format->data);
2340231200Smm  struct rar_br *br = &(rar->br);
2341231200Smm
2342231200Smm  if (rar->filterstart < end)
2343231200Smm    end = rar->filterstart;
2344231200Smm
2345231200Smm  while (1)
2346231200Smm  {
2347231200Smm    if (rar->output_last_match &&
2348231200Smm      lzss_position(&rar->lzss) + rar->lastlength <= end)
2349231200Smm    {
2350231200Smm      lzss_emit_match(rar, rar->lastoffset, rar->lastlength);
2351231200Smm      rar->output_last_match = 0;
2352231200Smm    }
2353231200Smm
2354231200Smm    if(rar->is_ppmd_block || rar->output_last_match ||
2355231200Smm      lzss_position(&rar->lzss) >= end)
2356231200Smm      return lzss_position(&rar->lzss);
2357231200Smm
2358231200Smm    if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
2359231200Smm      return (ARCHIVE_FATAL);
2360231200Smm    rar->output_last_match = 0;
2361231200Smm
2362231200Smm    if (symbol < 256)
2363231200Smm    {
2364231200Smm      lzss_emit_literal(rar, symbol);
2365231200Smm      continue;
2366231200Smm    }
2367231200Smm    else if (symbol == 256)
2368231200Smm    {
2369231200Smm      if (!rar_br_read_ahead(a, br, 1))
2370231200Smm        goto truncated_data;
2371231200Smm      newfile = !rar_br_bits(br, 1);
2372231200Smm      rar_br_consume(br, 1);
2373231200Smm
2374231200Smm      if(newfile)
2375231200Smm      {
2376231200Smm        rar->start_new_block = 1;
2377231200Smm        if (!rar_br_read_ahead(a, br, 1))
2378231200Smm          goto truncated_data;
2379231200Smm        rar->start_new_table = rar_br_bits(br, 1);
2380231200Smm        rar_br_consume(br, 1);
2381231200Smm        return lzss_position(&rar->lzss);
2382231200Smm      }
2383231200Smm      else
2384231200Smm      {
2385231200Smm        if (parse_codes(a) != ARCHIVE_OK)
2386231200Smm          return (ARCHIVE_FATAL);
2387231200Smm        continue;
2388231200Smm      }
2389231200Smm    }
2390231200Smm    else if(symbol==257)
2391231200Smm    {
2392231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2393231200Smm                        "Parsing filters is unsupported.");
2394231200Smm      return (ARCHIVE_FAILED);
2395231200Smm    }
2396231200Smm    else if(symbol==258)
2397231200Smm    {
2398231200Smm      if(rar->lastlength == 0)
2399231200Smm        continue;
2400231200Smm
2401231200Smm      offs = rar->lastoffset;
2402231200Smm      len = rar->lastlength;
2403231200Smm    }
2404231200Smm    else if (symbol <= 262)
2405231200Smm    {
2406231200Smm      offsindex = symbol - 259;
2407231200Smm      offs = rar->oldoffset[offsindex];
2408231200Smm
2409231200Smm      if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
2410231200Smm        goto bad_data;
2411231200Smm      if (lensymbol > sizeof(lengthbases)/sizeof(lengthbases[0]))
2412231200Smm        goto bad_data;
2413231200Smm      if (lensymbol > sizeof(lengthbits)/sizeof(lengthbits[0]))
2414231200Smm        goto bad_data;
2415231200Smm      len = lengthbases[lensymbol] + 2;
2416231200Smm      if (lengthbits[lensymbol] > 0) {
2417231200Smm        if (!rar_br_read_ahead(a, br, lengthbits[lensymbol]))
2418231200Smm          goto truncated_data;
2419231200Smm        len += rar_br_bits(br, lengthbits[lensymbol]);
2420231200Smm        rar_br_consume(br, lengthbits[lensymbol]);
2421231200Smm      }
2422231200Smm
2423231200Smm      for (i = offsindex; i > 0; i--)
2424231200Smm        rar->oldoffset[i] = rar->oldoffset[i-1];
2425231200Smm      rar->oldoffset[0] = offs;
2426231200Smm    }
2427231200Smm    else if(symbol<=270)
2428231200Smm    {
2429231200Smm      offs = shortbases[symbol-263] + 1;
2430231200Smm      if(shortbits[symbol-263] > 0) {
2431231200Smm        if (!rar_br_read_ahead(a, br, shortbits[symbol-263]))
2432231200Smm          goto truncated_data;
2433231200Smm        offs += rar_br_bits(br, shortbits[symbol-263]);
2434231200Smm        rar_br_consume(br, shortbits[symbol-263]);
2435231200Smm      }
2436231200Smm
2437231200Smm      len = 2;
2438231200Smm
2439231200Smm      for(i = 3; i > 0; i--)
2440231200Smm        rar->oldoffset[i] = rar->oldoffset[i-1];
2441231200Smm      rar->oldoffset[0] = offs;
2442231200Smm    }
2443231200Smm    else
2444231200Smm    {
2445231200Smm      if (symbol-271 > sizeof(lengthbases)/sizeof(lengthbases[0]))
2446231200Smm        goto bad_data;
2447231200Smm      if (symbol-271 > sizeof(lengthbits)/sizeof(lengthbits[0]))
2448231200Smm        goto bad_data;
2449231200Smm      len = lengthbases[symbol-271]+3;
2450231200Smm      if(lengthbits[symbol-271] > 0) {
2451231200Smm        if (!rar_br_read_ahead(a, br, lengthbits[symbol-271]))
2452231200Smm          goto truncated_data;
2453231200Smm        len += rar_br_bits(br, lengthbits[symbol-271]);
2454231200Smm        rar_br_consume(br, lengthbits[symbol-271]);
2455231200Smm      }
2456231200Smm
2457231200Smm      if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
2458231200Smm        goto bad_data;
2459231200Smm      if (offssymbol > sizeof(offsetbases)/sizeof(offsetbases[0]))
2460231200Smm        goto bad_data;
2461231200Smm      if (offssymbol > sizeof(offsetbits)/sizeof(offsetbits[0]))
2462231200Smm        goto bad_data;
2463231200Smm      offs = offsetbases[offssymbol]+1;
2464231200Smm      if(offsetbits[offssymbol] > 0)
2465231200Smm      {
2466231200Smm        if(offssymbol > 9)
2467231200Smm        {
2468231200Smm          if(offsetbits[offssymbol] > 4) {
2469231200Smm            if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4))
2470231200Smm              goto truncated_data;
2471231200Smm            offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4;
2472231200Smm            rar_br_consume(br, offsetbits[offssymbol] - 4);
2473231200Smm	  }
2474231200Smm
2475231200Smm          if(rar->numlowoffsetrepeats > 0)
2476231200Smm          {
2477231200Smm            rar->numlowoffsetrepeats--;
2478231200Smm            offs += rar->lastlowoffset;
2479231200Smm          }
2480231200Smm          else
2481231200Smm          {
2482231200Smm            if ((lowoffsetsymbol =
2483231200Smm              read_next_symbol(a, &rar->lowoffsetcode)) < 0)
2484231200Smm              return (ARCHIVE_FATAL);
2485231200Smm            if(lowoffsetsymbol == 16)
2486231200Smm            {
2487231200Smm              rar->numlowoffsetrepeats = 15;
2488231200Smm              offs += rar->lastlowoffset;
2489231200Smm            }
2490231200Smm            else
2491231200Smm            {
2492231200Smm              offs += lowoffsetsymbol;
2493231200Smm              rar->lastlowoffset = lowoffsetsymbol;
2494231200Smm            }
2495231200Smm          }
2496231200Smm        }
2497231200Smm        else {
2498231200Smm          if (!rar_br_read_ahead(a, br, offsetbits[offssymbol]))
2499231200Smm            goto truncated_data;
2500231200Smm          offs += rar_br_bits(br, offsetbits[offssymbol]);
2501231200Smm          rar_br_consume(br, offsetbits[offssymbol]);
2502231200Smm        }
2503231200Smm      }
2504231200Smm
2505231200Smm      if (offs >= 0x40000)
2506231200Smm        len++;
2507231200Smm      if (offs >= 0x2000)
2508231200Smm        len++;
2509231200Smm
2510231200Smm      for(i = 3; i > 0; i--)
2511231200Smm        rar->oldoffset[i] = rar->oldoffset[i-1];
2512231200Smm      rar->oldoffset[0] = offs;
2513231200Smm    }
2514231200Smm
2515231200Smm    rar->lastoffset = offs;
2516231200Smm    rar->lastlength = len;
2517231200Smm    rar->output_last_match = 1;
2518231200Smm  }
2519231200Smmtruncated_data:
2520231200Smm  archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2521231200Smm                    "Truncated RAR file data");
2522231200Smm  rar->valid = 0;
2523231200Smm  return (ARCHIVE_FATAL);
2524231200Smmbad_data:
2525231200Smm  archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2526231200Smm                    "Bad RAR file data");
2527231200Smm  return (ARCHIVE_FATAL);
2528231200Smm}
2529231200Smm
2530231200Smmstatic int
2531231200Smmcopy_from_lzss_window(struct archive_read *a, const void **buffer,
2532231200Smm                        int64_t startpos, int length)
2533231200Smm{
2534231200Smm  int windowoffs, firstpart;
2535231200Smm  struct rar *rar = (struct rar *)(a->format->data);
2536231200Smm
2537231200Smm  if (!rar->unp_buffer)
2538231200Smm  {
2539231200Smm    if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
2540231200Smm    {
2541231200Smm      archive_set_error(&a->archive, ENOMEM,
2542231200Smm                        "Unable to allocate memory for uncompressed data.");
2543231200Smm      return (ARCHIVE_FATAL);
2544231200Smm    }
2545231200Smm  }
2546231200Smm
2547231200Smm  windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
2548231200Smm  if(windowoffs + length <= lzss_size(&rar->lzss))
2549231200Smm    memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
2550231200Smm           length);
2551231200Smm  else
2552231200Smm  {
2553231200Smm    firstpart = lzss_size(&rar->lzss) - windowoffs;
2554231200Smm    if (firstpart < 0) {
2555231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2556231200Smm                        "Bad RAR file data");
2557231200Smm      return (ARCHIVE_FATAL);
2558231200Smm    }
2559231200Smm    if (firstpart < length) {
2560231200Smm      memcpy(&rar->unp_buffer[rar->unp_offset],
2561231200Smm             &rar->lzss.window[windowoffs], firstpart);
2562231200Smm      memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
2563231200Smm             &rar->lzss.window[0], length - firstpart);
2564231200Smm    } else
2565231200Smm      memcpy(&rar->unp_buffer[rar->unp_offset],
2566231200Smm             &rar->lzss.window[windowoffs], length);
2567231200Smm  }
2568231200Smm  rar->unp_offset += length;
2569231200Smm  if (rar->unp_offset >= rar->unp_buffer_size)
2570231200Smm    *buffer = rar->unp_buffer;
2571231200Smm  else
2572231200Smm    *buffer = NULL;
2573231200Smm  return (ARCHIVE_OK);
2574231200Smm}
2575