archive_read_support_format_rar.c revision 232153
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);
308232153Smmstatic time_t get_time(int);
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    }
760232153Smm    return (ret);
761232153Smm  }
762232153Smm
763232153Smm  /* Note: The "warn" return is just to inform the options
764232153Smm   * supervisor that we didn't handle it.  It will generate
765232153Smm   * a suitable error if no one used this option. */
766232153Smm  return (ARCHIVE_WARN);
767231200Smm}
768231200Smm
769231200Smmstatic int
770231200Smmarchive_read_format_rar_read_header(struct archive_read *a,
771231200Smm                                    struct archive_entry *entry)
772231200Smm{
773231200Smm  const void *h;
774231200Smm  const char *p;
775231200Smm  struct rar *rar;
776231200Smm  size_t skip;
777231200Smm  char head_type;
778231200Smm  int ret;
779231200Smm  unsigned flags;
780231200Smm
781231200Smm  a->archive.archive_format = ARCHIVE_FORMAT_RAR;
782231200Smm  if (a->archive.archive_format_name == NULL)
783231200Smm    a->archive.archive_format_name = "RAR";
784231200Smm
785231200Smm  rar = (struct rar *)(a->format->data);
786231200Smm
787231200Smm  /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if
788231200Smm  * this fails.
789231200Smm  */
790231200Smm  if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
791231200Smm    return (ARCHIVE_EOF);
792231200Smm
793231200Smm  p = h;
794231200Smm  if (rar->found_first_header == 0 &&
795231200Smm     ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) {
796231200Smm    /* This is an executable ? Must be self-extracting... */
797231200Smm    ret = skip_sfx(a);
798231200Smm    if (ret < ARCHIVE_WARN)
799231200Smm      return (ret);
800231200Smm  }
801231200Smm  rar->found_first_header = 1;
802231200Smm
803231200Smm  while (1)
804231200Smm  {
805231200Smm    unsigned long crc32_val;
806231200Smm
807231200Smm    if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
808231200Smm      return (ARCHIVE_FATAL);
809231200Smm    p = h;
810231200Smm
811231200Smm    head_type = p[2];
812231200Smm    switch(head_type)
813231200Smm    {
814231200Smm    case MARK_HEAD:
815231200Smm      if (memcmp(p, RAR_SIGNATURE, 7) != 0) {
816231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
817231200Smm          "Invalid marker header");
818231200Smm        return (ARCHIVE_FATAL);
819231200Smm      }
820231200Smm      __archive_read_consume(a, 7);
821231200Smm      break;
822231200Smm
823231200Smm    case MAIN_HEAD:
824231200Smm      rar->main_flags = archive_le16dec(p + 3);
825231200Smm      skip = archive_le16dec(p + 5);
826231200Smm      if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) {
827231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
828231200Smm          "Invalid header size");
829231200Smm        return (ARCHIVE_FATAL);
830231200Smm      }
831231200Smm      if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
832231200Smm        return (ARCHIVE_FATAL);
833231200Smm      p = h;
834231200Smm      memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1));
835231200Smm      memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1),
836231200Smm             sizeof(rar->reserved2));
837231200Smm      if (rar->main_flags & MHD_ENCRYPTVER) {
838231200Smm        if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) {
839231200Smm          archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
840231200Smm            "Invalid header size");
841231200Smm          return (ARCHIVE_FATAL);
842231200Smm        }
843231200Smm        rar->encryptver = *(p + 7 + sizeof(rar->reserved1) +
844231200Smm                            sizeof(rar->reserved2));
845231200Smm      }
846231200Smm
847231200Smm      if (rar->main_flags & MHD_VOLUME ||
848231200Smm          rar->main_flags & MHD_FIRSTVOLUME)
849231200Smm      {
850231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
851231200Smm                          "RAR volume support unavailable.");
852231200Smm        return (ARCHIVE_FATAL);
853231200Smm      }
854231200Smm      if (rar->main_flags & MHD_PASSWORD)
855231200Smm      {
856231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
857231200Smm                          "RAR encryption support unavailable.");
858231200Smm        return (ARCHIVE_FATAL);
859231200Smm      }
860231200Smm
861231200Smm      crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2);
862231200Smm      if ((crc32_val & 0xffff) != archive_le16dec(p)) {
863231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
864231200Smm          "Header CRC error");
865231200Smm        return (ARCHIVE_FATAL);
866231200Smm      }
867231200Smm      __archive_read_consume(a, skip);
868231200Smm      break;
869231200Smm
870231200Smm    case FILE_HEAD:
871231200Smm      return read_header(a, entry, head_type);
872231200Smm
873231200Smm    case COMM_HEAD:
874231200Smm    case AV_HEAD:
875231200Smm    case SUB_HEAD:
876231200Smm    case PROTECT_HEAD:
877231200Smm    case SIGN_HEAD:
878231200Smm      flags = archive_le16dec(p + 3);
879231200Smm      skip = archive_le16dec(p + 5);
880231200Smm      if (skip < 7) {
881231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
882231200Smm          "Invalid header size");
883231200Smm        return (ARCHIVE_FATAL);
884231200Smm      }
885231200Smm      if (skip > 7) {
886231200Smm        if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
887231200Smm          return (ARCHIVE_FATAL);
888231200Smm        p = h;
889231200Smm      }
890231200Smm      if (flags & HD_ADD_SIZE_PRESENT)
891231200Smm      {
892231200Smm        if (skip < 7 + 4) {
893231200Smm          archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
894231200Smm            "Invalid header size");
895231200Smm          return (ARCHIVE_FATAL);
896231200Smm        }
897231200Smm        skip += archive_le32dec(p + 7);
898231200Smm        if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
899231200Smm          return (ARCHIVE_FATAL);
900231200Smm        p = h;
901231200Smm      }
902231200Smm
903231200Smm      crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2);
904231200Smm      if ((crc32_val & 0xffff) != archive_le16dec(p)) {
905231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
906231200Smm          "Header CRC error");
907231200Smm        return (ARCHIVE_FATAL);
908231200Smm      }
909231200Smm      __archive_read_consume(a, skip);
910231200Smm      break;
911231200Smm
912231200Smm    case NEWSUB_HEAD:
913231200Smm      if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN)
914231200Smm        return ret;
915231200Smm      break;
916231200Smm
917231200Smm    case ENDARC_HEAD:
918231200Smm      return (ARCHIVE_EOF);
919231200Smm
920231200Smm    default:
921231200Smm      archive_set_error(&a->archive,  ARCHIVE_ERRNO_FILE_FORMAT,
922231200Smm                        "Bad RAR file");
923231200Smm      return (ARCHIVE_FATAL);
924231200Smm    }
925231200Smm  }
926231200Smm}
927231200Smm
928231200Smmstatic int
929231200Smmarchive_read_format_rar_read_data(struct archive_read *a, const void **buff,
930231200Smm                                  size_t *size, int64_t *offset)
931231200Smm{
932231200Smm  struct rar *rar = (struct rar *)(a->format->data);
933231200Smm  int ret;
934231200Smm
935231200Smm  if (rar->bytes_unconsumed > 0) {
936231200Smm      /* Consume as much as the decompressor actually used. */
937231200Smm      __archive_read_consume(a, rar->bytes_unconsumed);
938231200Smm      rar->bytes_unconsumed = 0;
939231200Smm  }
940231200Smm
941231200Smm  if (rar->entry_eof) {
942231200Smm    *buff = NULL;
943231200Smm    *size = 0;
944231200Smm    *offset = rar->offset;
945231200Smm    return (ARCHIVE_EOF);
946231200Smm  }
947231200Smm
948231200Smm  switch (rar->compression_method)
949231200Smm  {
950231200Smm  case COMPRESS_METHOD_STORE:
951231200Smm    ret = read_data_stored(a, buff, size, offset);
952231200Smm    break;
953231200Smm
954231200Smm  case COMPRESS_METHOD_FASTEST:
955231200Smm  case COMPRESS_METHOD_FAST:
956231200Smm  case COMPRESS_METHOD_NORMAL:
957231200Smm  case COMPRESS_METHOD_GOOD:
958231200Smm  case COMPRESS_METHOD_BEST:
959231200Smm    ret = read_data_compressed(a, buff, size, offset);
960231200Smm    if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
961231200Smm      __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
962231200Smm    break;
963231200Smm
964231200Smm  default:
965231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
966231200Smm                      "Unsupported compression method for RAR file.");
967231200Smm    ret = ARCHIVE_FATAL;
968231200Smm    break;
969231200Smm  }
970231200Smm  return (ret);
971231200Smm}
972231200Smm
973231200Smmstatic int
974231200Smmarchive_read_format_rar_read_data_skip(struct archive_read *a)
975231200Smm{
976231200Smm  struct rar *rar;
977231200Smm  int64_t bytes_skipped;
978231200Smm
979231200Smm  rar = (struct rar *)(a->format->data);
980231200Smm
981231200Smm  if (rar->bytes_unconsumed > 0) {
982231200Smm      /* Consume as much as the decompressor actually used. */
983231200Smm      __archive_read_consume(a, rar->bytes_unconsumed);
984231200Smm      rar->bytes_unconsumed = 0;
985231200Smm  }
986231200Smm
987231200Smm  if (rar->bytes_remaining > 0) {
988231200Smm    bytes_skipped = __archive_read_consume(a, rar->bytes_remaining);
989231200Smm    if (bytes_skipped < 0)
990231200Smm      return (ARCHIVE_FATAL);
991231200Smm  }
992231200Smm  return (ARCHIVE_OK);
993231200Smm}
994231200Smm
995231200Smmstatic int
996231200Smmarchive_read_format_rar_cleanup(struct archive_read *a)
997231200Smm{
998231200Smm  struct rar *rar;
999231200Smm
1000231200Smm  rar = (struct rar *)(a->format->data);
1001231200Smm  free_codes(a);
1002231200Smm  free(rar->filename);
1003231200Smm  free(rar->unp_buffer);
1004231200Smm  free(rar->lzss.window);
1005231200Smm  __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
1006231200Smm  free(rar);
1007231200Smm  (a->format->data) = NULL;
1008231200Smm  return (ARCHIVE_OK);
1009231200Smm}
1010231200Smm
1011231200Smmstatic int
1012231200Smmread_header(struct archive_read *a, struct archive_entry *entry,
1013231200Smm            char head_type)
1014231200Smm{
1015231200Smm  const void *h;
1016231200Smm  const char *p, *endp;
1017231200Smm  struct rar *rar;
1018231200Smm  struct rar_header rar_header;
1019231200Smm  struct rar_file_header file_header;
1020231200Smm  int64_t header_size;
1021231200Smm  unsigned filename_size, end;
1022231200Smm  char *filename;
1023231200Smm  char *strp;
1024231200Smm  char packed_size[8];
1025231200Smm  char unp_size[8];
1026232153Smm  int ttime;
1027231200Smm  struct archive_string_conv *sconv, *fn_sconv;
1028231200Smm  unsigned long crc32_val;
1029231200Smm  int ret = (ARCHIVE_OK), ret2;
1030231200Smm
1031231200Smm  rar = (struct rar *)(a->format->data);
1032231200Smm
1033231200Smm  /* Setup a string conversion object for non-rar-unicode filenames. */
1034231200Smm  sconv = rar->opt_sconv;
1035231200Smm  if (sconv == NULL) {
1036231200Smm    if (!rar->init_default_conversion) {
1037231200Smm      rar->sconv_default =
1038231200Smm          archive_string_default_conversion_for_read(
1039231200Smm            &(a->archive));
1040231200Smm      rar->init_default_conversion = 1;
1041231200Smm    }
1042231200Smm    sconv = rar->sconv_default;
1043231200Smm  }
1044231200Smm
1045231200Smm
1046231200Smm  if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
1047231200Smm    return (ARCHIVE_FATAL);
1048231200Smm  p = h;
1049231200Smm  memcpy(&rar_header, p, sizeof(rar_header));
1050231200Smm  rar->file_flags = archive_le16dec(rar_header.flags);
1051231200Smm  header_size = archive_le16dec(rar_header.size);
1052232153Smm  if (header_size < (int64_t)sizeof(file_header) + 7) {
1053231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1054231200Smm      "Invalid header size");
1055231200Smm    return (ARCHIVE_FATAL);
1056231200Smm  }
1057231200Smm  crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2);
1058231200Smm  __archive_read_consume(a, 7);
1059231200Smm
1060231200Smm  if (!(rar->file_flags & FHD_SOLID))
1061231200Smm  {
1062231200Smm    rar->compression_method = 0;
1063231200Smm    rar->packed_size = 0;
1064231200Smm    rar->unp_size = 0;
1065231200Smm    rar->mtime = 0;
1066231200Smm    rar->ctime = 0;
1067231200Smm    rar->atime = 0;
1068231200Smm    rar->arctime = 0;
1069231200Smm    rar->mode = 0;
1070231200Smm    memset(&rar->salt, 0, sizeof(rar->salt));
1071231200Smm    rar->atime = 0;
1072231200Smm    rar->ansec = 0;
1073231200Smm    rar->ctime = 0;
1074231200Smm    rar->cnsec = 0;
1075231200Smm    rar->mtime = 0;
1076231200Smm    rar->mnsec = 0;
1077231200Smm    rar->arctime = 0;
1078231200Smm    rar->arcnsec = 0;
1079231200Smm  }
1080231200Smm  else
1081231200Smm  {
1082231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1083231200Smm                      "RAR solid archive support unavailable.");
1084231200Smm    return (ARCHIVE_FATAL);
1085231200Smm  }
1086231200Smm
1087231200Smm  if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL)
1088231200Smm    return (ARCHIVE_FATAL);
1089231200Smm
1090231200Smm  /* File Header CRC check. */
1091231200Smm  crc32_val = crc32(crc32_val, h, header_size - 7);
1092231200Smm  if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) {
1093231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1094231200Smm      "Header CRC error");
1095231200Smm    return (ARCHIVE_FATAL);
1096231200Smm  }
1097231200Smm  /* If no CRC error, Go on parsing File Header. */
1098231200Smm  p = h;
1099231200Smm  endp = p + header_size - 7;
1100231200Smm  memcpy(&file_header, p, sizeof(file_header));
1101231200Smm  p += sizeof(file_header);
1102231200Smm
1103231200Smm  rar->compression_method = file_header.method;
1104231200Smm
1105232153Smm  ttime = archive_le32dec(file_header.file_time);
1106232153Smm  rar->mtime = get_time(ttime);
1107231200Smm
1108231200Smm  rar->file_crc = archive_le32dec(file_header.file_crc);
1109231200Smm
1110231200Smm  if (rar->file_flags & FHD_PASSWORD)
1111231200Smm  {
1112231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1113231200Smm                      "RAR encryption support unavailable.");
1114231200Smm    return (ARCHIVE_FATAL);
1115231200Smm  }
1116231200Smm
1117231200Smm  if (rar->file_flags & FHD_LARGE)
1118231200Smm  {
1119231200Smm    memcpy(packed_size, file_header.pack_size, 4);
1120231200Smm    memcpy(packed_size + 4, p, 4); /* High pack size */
1121231200Smm    p += 4;
1122231200Smm    memcpy(unp_size, file_header.unp_size, 4);
1123231200Smm    memcpy(unp_size + 4, p, 4); /* High unpack size */
1124231200Smm    p += 4;
1125231200Smm    rar->packed_size = archive_le64dec(&packed_size);
1126231200Smm    rar->unp_size = archive_le64dec(&unp_size);
1127231200Smm  }
1128231200Smm  else
1129231200Smm  {
1130231200Smm    rar->packed_size = archive_le32dec(file_header.pack_size);
1131231200Smm    rar->unp_size = archive_le32dec(file_header.unp_size);
1132231200Smm  }
1133231200Smm
1134231200Smm  /* TODO: Need to use CRC check for these kind of cases.
1135231200Smm   * For now, check if sizes are not < 0.
1136231200Smm   */
1137231200Smm  if (rar->packed_size < 0 || rar->unp_size < 0)
1138231200Smm  {
1139231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1140231200Smm                      "Invalid sizes specified.");
1141231200Smm    return (ARCHIVE_FATAL);
1142231200Smm  }
1143231200Smm
1144231200Smm  /* TODO: RARv3 subblocks contain comments. For now the complete block is
1145231200Smm   * consumed at the end.
1146231200Smm   */
1147231200Smm  if (head_type == NEWSUB_HEAD) {
1148231200Smm    size_t distance = p - (const char *)h;
1149231200Smm    header_size += rar->packed_size;
1150231200Smm    /* Make sure we have the extended data. */
1151231200Smm    if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL)
1152231200Smm        return (ARCHIVE_FATAL);
1153231200Smm    p = h;
1154231200Smm    endp = p + header_size - 7;
1155231200Smm    p += distance;
1156231200Smm  }
1157231200Smm
1158231200Smm  filename_size = archive_le16dec(file_header.name_size);
1159231200Smm  if (p + filename_size > endp) {
1160231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1161231200Smm      "Invalid filename size");
1162231200Smm    return (ARCHIVE_FATAL);
1163231200Smm  }
1164231200Smm  if (rar->filename_allocated < filename_size+2) {
1165231200Smm    rar->filename = realloc(rar->filename, filename_size+2);
1166231200Smm    if (rar->filename == NULL) {
1167231200Smm      archive_set_error(&a->archive, ENOMEM,
1168231200Smm                        "Couldn't allocate memory.");
1169231200Smm      return (ARCHIVE_FATAL);
1170231200Smm    }
1171231200Smm  }
1172231200Smm  filename = rar->filename;
1173231200Smm  memcpy(filename, p, filename_size);
1174231200Smm  filename[filename_size] = '\0';
1175231200Smm  if (rar->file_flags & FHD_UNICODE)
1176231200Smm  {
1177231200Smm    if (filename_size != strlen(filename))
1178231200Smm    {
1179231200Smm      unsigned char highbyte, flagbits, flagbyte, length, offset;
1180231200Smm
1181231200Smm      end = filename_size;
1182231200Smm      filename_size = 0;
1183231200Smm      offset = strlen(filename) + 1;
1184231200Smm      highbyte = *(p + offset++);
1185231200Smm      flagbits = 0;
1186231200Smm      flagbyte = 0;
1187231200Smm      while (offset < end && filename_size < end)
1188231200Smm      {
1189231200Smm        if (!flagbits)
1190231200Smm        {
1191231200Smm          flagbyte = *(p + offset++);
1192231200Smm          flagbits = 8;
1193231200Smm        }
1194231200Smm
1195231200Smm        flagbits -= 2;
1196231200Smm        switch((flagbyte >> flagbits) & 3)
1197231200Smm        {
1198231200Smm          case 0:
1199231200Smm            filename[filename_size++] = '\0';
1200231200Smm            filename[filename_size++] = *(p + offset++);
1201231200Smm            break;
1202231200Smm          case 1:
1203231200Smm            filename[filename_size++] = highbyte;
1204231200Smm            filename[filename_size++] = *(p + offset++);
1205231200Smm            break;
1206231200Smm          case 2:
1207231200Smm            filename[filename_size++] = *(p + offset + 1);
1208231200Smm            filename[filename_size++] = *(p + offset);
1209231200Smm            offset += 2;
1210231200Smm            break;
1211231200Smm          case 3:
1212231200Smm          {
1213231200Smm            length = *(p + offset++);
1214231200Smm            while (length)
1215231200Smm            {
1216231200Smm	          if (filename_size >= end)
1217231200Smm			    break;
1218231200Smm              filename[filename_size++] = *(p + offset);
1219231200Smm              length--;
1220231200Smm            }
1221231200Smm          }
1222231200Smm          break;
1223231200Smm        }
1224231200Smm      }
1225231200Smm      if (filename_size >= end) {
1226231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1227231200Smm          "Invalid filename");
1228231200Smm        return (ARCHIVE_FATAL);
1229231200Smm      }
1230231200Smm      filename[filename_size++] = '\0';
1231231200Smm      filename[filename_size++] = '\0';
1232231200Smm
1233231200Smm      /* Decoded unicode form is UTF-16BE, so we have to update a string
1234231200Smm       * conversion object for it. */
1235231200Smm      if (rar->sconv_utf16be == NULL) {
1236231200Smm        rar->sconv_utf16be = archive_string_conversion_from_charset(
1237231200Smm           &a->archive, "UTF-16BE", 1);
1238231200Smm        if (rar->sconv_utf16be == NULL)
1239231200Smm          return (ARCHIVE_FATAL);
1240231200Smm      }
1241231200Smm      fn_sconv = rar->sconv_utf16be;
1242231200Smm
1243231200Smm      strp = filename;
1244231200Smm      while (memcmp(strp, "\x00\x00", 2))
1245231200Smm      {
1246231200Smm        if (!memcmp(strp, "\x00\\", 2))
1247231200Smm          *(strp + 1) = '/';
1248231200Smm        strp += 2;
1249231200Smm      }
1250231200Smm      p += offset;
1251231200Smm    } else {
1252231200Smm      /*
1253231200Smm       * If FHD_UNICODE is set but no unicode data, this file name form
1254231200Smm       * is UTF-8, so we have to update a string conversion object for
1255231200Smm       * it accordingly.
1256231200Smm       */
1257231200Smm      if (rar->sconv_utf8 == NULL) {
1258231200Smm        rar->sconv_utf8 = archive_string_conversion_from_charset(
1259231200Smm           &a->archive, "UTF-8", 1);
1260231200Smm        if (rar->sconv_utf8 == NULL)
1261231200Smm          return (ARCHIVE_FATAL);
1262231200Smm      }
1263231200Smm      fn_sconv = rar->sconv_utf8;
1264231200Smm      while ((strp = strchr(filename, '\\')) != NULL)
1265231200Smm        *strp = '/';
1266231200Smm      p += filename_size;
1267231200Smm    }
1268231200Smm  }
1269231200Smm  else
1270231200Smm  {
1271231200Smm    fn_sconv = sconv;
1272231200Smm    while ((strp = strchr(filename, '\\')) != NULL)
1273231200Smm      *strp = '/';
1274231200Smm    p += filename_size;
1275231200Smm  }
1276231200Smm
1277231200Smm  if (rar->file_flags & FHD_SALT)
1278231200Smm  {
1279231200Smm    if (p + 8 > endp) {
1280231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1281231200Smm        "Invalid header size");
1282231200Smm      return (ARCHIVE_FATAL);
1283231200Smm    }
1284231200Smm    memcpy(rar->salt, p, 8);
1285231200Smm    p += 8;
1286231200Smm  }
1287231200Smm
1288231200Smm  if (rar->file_flags & FHD_EXTTIME) {
1289231200Smm    if (read_exttime(p, rar, endp) < 0) {
1290231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1291231200Smm        "Invalid header size");
1292231200Smm      return (ARCHIVE_FATAL);
1293231200Smm    }
1294231200Smm  }
1295231200Smm
1296231200Smm  __archive_read_consume(a, header_size - 7);
1297231200Smm
1298231200Smm  switch(file_header.host_os)
1299231200Smm  {
1300231200Smm  case OS_MSDOS:
1301231200Smm  case OS_OS2:
1302231200Smm  case OS_WIN32:
1303231200Smm    rar->mode = archive_le32dec(file_header.file_attr);
1304231200Smm    if (rar->mode & FILE_ATTRIBUTE_DIRECTORY)
1305231200Smm      rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
1306231200Smm    else
1307231200Smm      rar->mode = AE_IFREG;
1308231200Smm    rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1309231200Smm    break;
1310231200Smm
1311231200Smm  case OS_UNIX:
1312231200Smm  case OS_MAC_OS:
1313231200Smm  case OS_BEOS:
1314231200Smm    rar->mode = archive_le32dec(file_header.file_attr);
1315231200Smm    break;
1316231200Smm
1317231200Smm  default:
1318231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1319231200Smm                      "Unknown file attributes from RAR file's host OS");
1320231200Smm    return (ARCHIVE_FATAL);
1321231200Smm  }
1322231200Smm
1323231200Smm  rar->bytes_remaining = rar->packed_size;
1324231200Smm  rar->bytes_uncopied = rar->bytes_unconsumed = 0;
1325231200Smm  rar->lzss.position = rar->dictionary_size = rar->offset = 0;
1326231200Smm  rar->offset_outgoing = 0;
1327231200Smm  rar->br.cache_avail = 0;
1328231200Smm  rar->br.avail_in = 0;
1329231200Smm  rar->crc_calculated = 0;
1330231200Smm  rar->entry_eof = 0;
1331231200Smm  rar->valid = 1;
1332231200Smm  rar->is_ppmd_block = 0;
1333231200Smm  rar->start_new_table = 1;
1334231200Smm  free(rar->unp_buffer);
1335231200Smm  rar->unp_buffer = NULL;
1336231200Smm  rar->unp_offset = 0;
1337231200Smm  rar->unp_buffer_size = UNP_BUFFER_SIZE;
1338231200Smm  memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
1339231200Smm  __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
1340231200Smm  rar->ppmd_valid = rar->ppmd_eod = 0;
1341231200Smm
1342231200Smm  /* Don't set any archive entries for non-file header types */
1343231200Smm  if (head_type == NEWSUB_HEAD)
1344231200Smm    return ret;
1345231200Smm
1346231200Smm  archive_entry_set_mtime(entry, rar->mtime, rar->mnsec);
1347231200Smm  archive_entry_set_ctime(entry, rar->ctime, rar->cnsec);
1348231200Smm  archive_entry_set_atime(entry, rar->atime, rar->ansec);
1349231200Smm  archive_entry_set_size(entry, rar->unp_size);
1350231200Smm  archive_entry_set_mode(entry, rar->mode);
1351231200Smm
1352231200Smm  if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv))
1353231200Smm  {
1354231200Smm    if (errno == ENOMEM)
1355231200Smm    {
1356231200Smm      archive_set_error(&a->archive, ENOMEM,
1357231200Smm                        "Can't allocate memory for Pathname");
1358231200Smm      return (ARCHIVE_FATAL);
1359231200Smm    }
1360231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1361231200Smm                      "Pathname cannot be converted from %s to current locale.",
1362231200Smm                      archive_string_conversion_charset_name(fn_sconv));
1363231200Smm    ret = (ARCHIVE_WARN);
1364231200Smm  }
1365231200Smm
1366231200Smm  if (((rar->mode) & AE_IFMT) == AE_IFLNK)
1367231200Smm  {
1368231200Smm    /* Make sure a symbolic-link file does not have its body. */
1369231200Smm    rar->bytes_remaining = 0;
1370231200Smm    archive_entry_set_size(entry, 0);
1371231200Smm
1372231200Smm    /* Read a symbolic-link name. */
1373231200Smm    if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN))
1374231200Smm      return ret2;
1375231200Smm    if (ret > ret2)
1376231200Smm      ret = ret2;
1377231200Smm  }
1378231200Smm
1379231200Smm  if (rar->bytes_remaining == 0)
1380231200Smm    rar->entry_eof = 1;
1381231200Smm
1382231200Smm  return ret;
1383231200Smm}
1384231200Smm
1385231200Smmstatic time_t
1386232153Smmget_time(int ttime)
1387231200Smm{
1388231200Smm  struct tm tm;
1389232153Smm  tm.tm_sec = 2 * (ttime & 0x1f);
1390232153Smm  tm.tm_min = (ttime >> 5) & 0x3f;
1391232153Smm  tm.tm_hour = (ttime >> 11) & 0x1f;
1392232153Smm  tm.tm_mday = (ttime >> 16) & 0x1f;
1393232153Smm  tm.tm_mon = ((ttime >> 21) & 0x0f) - 1;
1394232153Smm  tm.tm_year = ((ttime >> 25) & 0x7f) + 80;
1395231200Smm  tm.tm_isdst = -1;
1396231200Smm  return mktime(&tm);
1397231200Smm}
1398231200Smm
1399231200Smmstatic int
1400231200Smmread_exttime(const char *p, struct rar *rar, const char *endp)
1401231200Smm{
1402231200Smm  unsigned rmode, flags, rem, j, count;
1403232153Smm  int ttime, i;
1404231200Smm  struct tm *tm;
1405231200Smm  time_t t;
1406231200Smm  long nsec;
1407231200Smm
1408231200Smm  if (p + 2 > endp)
1409231200Smm    return (-1);
1410231200Smm  flags = archive_le16dec(p);
1411231200Smm  p += 2;
1412231200Smm
1413231200Smm  for (i = 3; i >= 0; i--)
1414231200Smm  {
1415231200Smm    t = 0;
1416231200Smm    if (i == 3)
1417231200Smm      t = rar->mtime;
1418231200Smm    rmode = flags >> i * 4;
1419231200Smm    if (rmode & 8)
1420231200Smm    {
1421231200Smm      if (!t)
1422231200Smm      {
1423231200Smm        if (p + 4 > endp)
1424231200Smm          return (-1);
1425232153Smm        ttime = archive_le32dec(p);
1426232153Smm        t = get_time(ttime);
1427231200Smm        p += 4;
1428231200Smm      }
1429231200Smm      rem = 0;
1430231200Smm      count = rmode & 3;
1431231200Smm      if (p + count > endp)
1432231200Smm        return (-1);
1433231200Smm      for (j = 0; j < count; j++)
1434231200Smm      {
1435231200Smm        rem = ((*p) << 16) | (rem >> 8);
1436231200Smm        p++;
1437231200Smm      }
1438231200Smm      tm = localtime(&t);
1439231200Smm      nsec = tm->tm_sec + rem / NS_UNIT;
1440231200Smm      if (rmode & 4)
1441231200Smm      {
1442231200Smm        tm->tm_sec++;
1443231200Smm        t = mktime(tm);
1444231200Smm      }
1445231200Smm      if (i == 3)
1446231200Smm      {
1447231200Smm        rar->mtime = t;
1448231200Smm        rar->mnsec = nsec;
1449231200Smm      }
1450231200Smm      else if (i == 2)
1451231200Smm      {
1452231200Smm        rar->ctime = t;
1453231200Smm        rar->cnsec = nsec;
1454231200Smm      }
1455231200Smm      else if (i == 1)
1456231200Smm      {
1457231200Smm        rar->atime = t;
1458231200Smm        rar->ansec = nsec;
1459231200Smm      }
1460231200Smm      else
1461231200Smm      {
1462231200Smm        rar->arctime = t;
1463231200Smm        rar->arcnsec = nsec;
1464231200Smm      }
1465231200Smm    }
1466231200Smm  }
1467231200Smm  return (0);
1468231200Smm}
1469231200Smm
1470231200Smmstatic int
1471231200Smmread_symlink_stored(struct archive_read *a, struct archive_entry *entry,
1472231200Smm                    struct archive_string_conv *sconv)
1473231200Smm{
1474231200Smm  const void *h;
1475231200Smm  const char *p;
1476231200Smm  struct rar *rar;
1477231200Smm  int ret = (ARCHIVE_OK);
1478231200Smm
1479231200Smm  rar = (struct rar *)(a->format->data);
1480231200Smm  if ((h = __archive_read_ahead(a, rar->packed_size, NULL)) == NULL)
1481231200Smm    return (ARCHIVE_FATAL);
1482231200Smm  p = h;
1483231200Smm
1484231200Smm  if (archive_entry_copy_symlink_l(entry, p, rar->packed_size, sconv))
1485231200Smm  {
1486231200Smm    if (errno == ENOMEM)
1487231200Smm    {
1488231200Smm      archive_set_error(&a->archive, ENOMEM,
1489231200Smm                        "Can't allocate memory for link");
1490231200Smm      return (ARCHIVE_FATAL);
1491231200Smm    }
1492231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1493231200Smm                      "link cannot be converted from %s to current locale.",
1494231200Smm                      archive_string_conversion_charset_name(sconv));
1495231200Smm    ret = (ARCHIVE_WARN);
1496231200Smm  }
1497231200Smm  __archive_read_consume(a, rar->packed_size);
1498231200Smm  return ret;
1499231200Smm}
1500231200Smm
1501231200Smmstatic int
1502231200Smmread_data_stored(struct archive_read *a, const void **buff, size_t *size,
1503231200Smm                 int64_t *offset)
1504231200Smm{
1505231200Smm  struct rar *rar;
1506231200Smm  ssize_t bytes_avail;
1507231200Smm
1508231200Smm  rar = (struct rar *)(a->format->data);
1509231200Smm  if (rar->bytes_remaining == 0)
1510231200Smm  {
1511231200Smm    *buff = NULL;
1512231200Smm    *size = 0;
1513231200Smm    *offset = rar->offset;
1514231200Smm    if (rar->file_crc != rar->crc_calculated) {
1515231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1516231200Smm                        "File CRC error");
1517231200Smm      return (ARCHIVE_FATAL);
1518231200Smm    }
1519231200Smm    rar->entry_eof = 1;
1520231200Smm    return (ARCHIVE_EOF);
1521231200Smm  }
1522231200Smm
1523231200Smm  *buff = __archive_read_ahead(a, 1, &bytes_avail);
1524231200Smm  if (bytes_avail <= 0)
1525231200Smm  {
1526231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1527231200Smm                      "Truncated RAR file data");
1528231200Smm    return (ARCHIVE_FATAL);
1529231200Smm  }
1530231200Smm  if (bytes_avail > rar->bytes_remaining)
1531231200Smm    bytes_avail = rar->bytes_remaining;
1532231200Smm
1533231200Smm  *size = bytes_avail;
1534231200Smm  *offset = rar->offset;
1535231200Smm  rar->offset += bytes_avail;
1536231200Smm  rar->bytes_remaining -= bytes_avail;
1537231200Smm  rar->bytes_unconsumed = bytes_avail;
1538231200Smm  /* Calculate File CRC. */
1539231200Smm  rar->crc_calculated = crc32(rar->crc_calculated, *buff, bytes_avail);
1540231200Smm  return (ARCHIVE_OK);
1541231200Smm}
1542231200Smm
1543231200Smmstatic int
1544231200Smmread_data_compressed(struct archive_read *a, const void **buff, size_t *size,
1545231200Smm               int64_t *offset)
1546231200Smm{
1547231200Smm  struct rar *rar;
1548231200Smm  int64_t start, end, actualend;
1549231200Smm  size_t bs;
1550231200Smm  int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i;
1551231200Smm
1552231200Smm  rar = (struct rar *)(a->format->data);
1553231200Smm
1554231200Smm  do {
1555231200Smm    if (!rar->valid)
1556231200Smm      return (ARCHIVE_FATAL);
1557231200Smm    if (rar->ppmd_eod ||
1558231200Smm       (rar->dictionary_size && rar->offset >= rar->unp_size))
1559231200Smm    {
1560231200Smm      if (rar->unp_offset > 0) {
1561231200Smm        /*
1562231200Smm         * We have unprocessed extracted data. write it out.
1563231200Smm         */
1564231200Smm        *buff = rar->unp_buffer;
1565231200Smm        *size = rar->unp_offset;
1566231200Smm        *offset = rar->offset_outgoing;
1567231200Smm        rar->offset_outgoing += *size;
1568231200Smm        /* Calculate File CRC. */
1569231200Smm        rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
1570231200Smm        rar->unp_offset = 0;
1571231200Smm        return (ARCHIVE_OK);
1572231200Smm      }
1573231200Smm      *buff = NULL;
1574231200Smm      *size = 0;
1575231200Smm      *offset = rar->offset;
1576231200Smm      if (rar->file_crc != rar->crc_calculated) {
1577231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1578231200Smm                          "File CRC error");
1579231200Smm        return (ARCHIVE_FATAL);
1580231200Smm      }
1581231200Smm      rar->entry_eof = 1;
1582231200Smm      return (ARCHIVE_EOF);
1583231200Smm    }
1584231200Smm
1585231200Smm    if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0)
1586231200Smm    {
1587231200Smm      if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
1588231200Smm        bs = rar->unp_buffer_size - rar->unp_offset;
1589231200Smm      else
1590231200Smm        bs = rar->bytes_uncopied;
1591231200Smm      ret = copy_from_lzss_window(a, buff, rar->offset, bs);
1592231200Smm      if (ret != ARCHIVE_OK)
1593231200Smm        return (ret);
1594231200Smm      rar->offset += bs;
1595231200Smm      rar->bytes_uncopied -= bs;
1596231200Smm      if (*buff != NULL) {
1597231200Smm        rar->unp_offset = 0;
1598231200Smm        *size = rar->unp_buffer_size;
1599231200Smm        *offset = rar->offset_outgoing;
1600231200Smm        rar->offset_outgoing += *size;
1601231200Smm        /* Calculate File CRC. */
1602231200Smm        rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
1603231200Smm        return (ret);
1604231200Smm      }
1605231200Smm      continue;
1606231200Smm    }
1607231200Smm
1608231200Smm    if (!rar->br.next_in &&
1609231200Smm      (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN)
1610231200Smm      return (ret);
1611231200Smm    if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN)))
1612231200Smm      return (ret);
1613231200Smm
1614231200Smm    if (rar->is_ppmd_block)
1615231200Smm    {
1616231200Smm      if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1617231200Smm        &rar->ppmd7_context, &rar->range_dec.p)) < 0)
1618231200Smm      {
1619231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1620231200Smm                          "Invalid symbol");
1621231200Smm        return (ARCHIVE_FATAL);
1622231200Smm      }
1623231200Smm      if(sym != rar->ppmd_escape)
1624231200Smm      {
1625231200Smm        lzss_emit_literal(rar, sym);
1626231200Smm        rar->bytes_uncopied++;
1627231200Smm      }
1628231200Smm      else
1629231200Smm      {
1630231200Smm        if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1631231200Smm          &rar->ppmd7_context, &rar->range_dec.p)) < 0)
1632231200Smm        {
1633231200Smm          archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1634231200Smm                            "Invalid symbol");
1635231200Smm          return (ARCHIVE_FATAL);
1636231200Smm        }
1637231200Smm
1638231200Smm        switch(code)
1639231200Smm        {
1640231200Smm          case 0:
1641231200Smm            rar->start_new_table = 1;
1642231200Smm            return read_data_compressed(a, buff, size, offset);
1643231200Smm
1644231200Smm          case 2:
1645231200Smm            rar->ppmd_eod = 1;/* End Of ppmd Data. */
1646231200Smm            continue;
1647231200Smm
1648231200Smm          case 3:
1649231200Smm            archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1650231200Smm                              "Parsing filters is unsupported.");
1651231200Smm            return (ARCHIVE_FAILED);
1652231200Smm
1653231200Smm          case 4:
1654231200Smm            lzss_offset = 0;
1655231200Smm            for (i = 2; i >= 0; i--)
1656231200Smm            {
1657231200Smm              if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1658231200Smm                &rar->ppmd7_context, &rar->range_dec.p)) < 0)
1659231200Smm              {
1660231200Smm                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1661231200Smm                                  "Invalid symbol");
1662231200Smm                return (ARCHIVE_FATAL);
1663231200Smm              }
1664231200Smm              lzss_offset |= code << (i * 8);
1665231200Smm            }
1666231200Smm            if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1667231200Smm              &rar->ppmd7_context, &rar->range_dec.p)) < 0)
1668231200Smm            {
1669231200Smm              archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1670231200Smm                                "Invalid symbol");
1671231200Smm              return (ARCHIVE_FATAL);
1672231200Smm            }
1673231200Smm            lzss_emit_match(rar, lzss_offset + 2, length + 32);
1674231200Smm            rar->bytes_uncopied += length + 32;
1675231200Smm            break;
1676231200Smm
1677231200Smm          case 5:
1678231200Smm            if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
1679231200Smm              &rar->ppmd7_context, &rar->range_dec.p)) < 0)
1680231200Smm            {
1681231200Smm              archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1682231200Smm                                "Invalid symbol");
1683231200Smm              return (ARCHIVE_FATAL);
1684231200Smm            }
1685231200Smm            lzss_emit_match(rar, 1, length + 4);
1686231200Smm            rar->bytes_uncopied += length + 4;
1687231200Smm            break;
1688231200Smm
1689231200Smm         default:
1690231200Smm           lzss_emit_literal(rar, sym);
1691231200Smm           rar->bytes_uncopied++;
1692231200Smm        }
1693231200Smm      }
1694231200Smm    }
1695231200Smm    else
1696231200Smm    {
1697231200Smm      start = rar->offset;
1698231200Smm      end = start + rar->dictionary_size;
1699231200Smm      rar->filterstart = INT64_MAX;
1700231200Smm
1701231200Smm      if ((actualend = expand(a, end)) < 0)
1702231200Smm        return ((int)actualend);
1703231200Smm
1704231200Smm      rar->bytes_uncopied = actualend - start;
1705231200Smm      if (rar->bytes_uncopied == 0) {
1706231200Smm          /* Broken RAR files cause this case.
1707231200Smm          * NOTE: If this case were possible on a normal RAR file
1708231200Smm          * we would find out where it was actually bad and
1709231200Smm          * what we would do to solve it. */
1710231200Smm          archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1711231200Smm                            "Internal error extracting RAR file");
1712231200Smm          return (ARCHIVE_FATAL);
1713231200Smm      }
1714231200Smm    }
1715231200Smm    if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
1716231200Smm      bs = rar->unp_buffer_size - rar->unp_offset;
1717231200Smm    else
1718231200Smm      bs = rar->bytes_uncopied;
1719231200Smm    ret = copy_from_lzss_window(a, buff, rar->offset, bs);
1720231200Smm    if (ret != ARCHIVE_OK)
1721231200Smm      return (ret);
1722231200Smm    rar->offset += bs;
1723231200Smm    rar->bytes_uncopied -= bs;
1724231200Smm    /*
1725231200Smm     * If *buff is NULL, it means unp_buffer is not full.
1726231200Smm     * So we have to continue extracting a RAR file.
1727231200Smm     */
1728231200Smm  } while (*buff == NULL);
1729231200Smm
1730231200Smm  rar->unp_offset = 0;
1731231200Smm  *size = rar->unp_buffer_size;
1732231200Smm  *offset = rar->offset_outgoing;
1733231200Smm  rar->offset_outgoing += *size;
1734231200Smm  /* Calculate File CRC. */
1735231200Smm  rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
1736231200Smm  return ret;
1737231200Smm}
1738231200Smm
1739231200Smmstatic int
1740231200Smmparse_codes(struct archive_read *a)
1741231200Smm{
1742231200Smm  int i, j, val, n, r;
1743231200Smm  unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags;
1744231200Smm  unsigned int maxorder;
1745231200Smm  struct huffman_code precode;
1746231200Smm  struct rar *rar = (struct rar *)(a->format->data);
1747231200Smm  struct rar_br *br = &(rar->br);
1748231200Smm
1749231200Smm  free_codes(a);
1750231200Smm
1751231200Smm  /* Skip to the next byte */
1752231200Smm  rar_br_consume_unalined_bits(br);
1753231200Smm
1754231200Smm  /* PPMd block flag */
1755231200Smm  if (!rar_br_read_ahead(a, br, 1))
1756231200Smm    goto truncated_data;
1757231200Smm  if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0)
1758231200Smm  {
1759231200Smm    rar_br_consume(br, 1);
1760231200Smm    if (!rar_br_read_ahead(a, br, 7))
1761231200Smm      goto truncated_data;
1762231200Smm    ppmd_flags = rar_br_bits(br, 7);
1763231200Smm    rar_br_consume(br, 7);
1764231200Smm
1765231200Smm    /* Memory is allocated in MB */
1766231200Smm    if (ppmd_flags & 0x20)
1767231200Smm    {
1768231200Smm      if (!rar_br_read_ahead(a, br, 8))
1769231200Smm        goto truncated_data;
1770231200Smm      rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20;
1771231200Smm      rar_br_consume(br, 8);
1772231200Smm    }
1773231200Smm
1774231200Smm    if (ppmd_flags & 0x40)
1775231200Smm    {
1776231200Smm      if (!rar_br_read_ahead(a, br, 8))
1777231200Smm        goto truncated_data;
1778231200Smm      rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8);
1779231200Smm      rar_br_consume(br, 8);
1780231200Smm    }
1781231200Smm    else
1782231200Smm      rar->ppmd_escape = 2;
1783231200Smm
1784231200Smm    if (ppmd_flags & 0x20)
1785231200Smm    {
1786231200Smm      maxorder = (ppmd_flags & 0x1F) + 1;
1787231200Smm      if(maxorder > 16)
1788231200Smm        maxorder = 16 + (maxorder - 16) * 3;
1789231200Smm
1790231200Smm      if (maxorder == 1)
1791231200Smm      {
1792231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1793231200Smm                          "Truncated RAR file data");
1794231200Smm        return (ARCHIVE_FATAL);
1795231200Smm      }
1796231200Smm
1797231200Smm      /* Make sure ppmd7_contest is freed before Ppmd7_Construct
1798231200Smm       * because reading a broken file cause this abnormal sequence. */
1799231200Smm      __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
1800231200Smm
1801231200Smm      rar->bytein.a = a;
1802231200Smm      rar->bytein.Read = &ppmd_read;
1803231200Smm      __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec);
1804231200Smm      rar->range_dec.Stream = &rar->bytein;
1805231200Smm      __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context);
1806231200Smm
1807231200Smm      if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context,
1808231200Smm        rar->dictionary_size, &g_szalloc))
1809231200Smm      {
1810231200Smm        archive_set_error(&a->archive, ENOMEM,
1811231200Smm                          "Out of memory");
1812231200Smm        return (ARCHIVE_FATAL);
1813231200Smm      }
1814231200Smm      if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec))
1815231200Smm      {
1816231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1817231200Smm                          "Unable to initialize PPMd range decoder");
1818231200Smm        return (ARCHIVE_FATAL);
1819231200Smm      }
1820231200Smm      __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder);
1821231200Smm      rar->ppmd_valid = 1;
1822231200Smm    }
1823231200Smm    else
1824231200Smm    {
1825231200Smm      if (!rar->ppmd_valid) {
1826231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1827231200Smm                          "Invalid PPMd sequence");
1828231200Smm        return (ARCHIVE_FATAL);
1829231200Smm      }
1830231200Smm      if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec))
1831231200Smm      {
1832231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1833231200Smm                          "Unable to initialize PPMd range decoder");
1834231200Smm        return (ARCHIVE_FATAL);
1835231200Smm      }
1836231200Smm    }
1837231200Smm  }
1838231200Smm  else
1839231200Smm  {
1840231200Smm    rar_br_consume(br, 1);
1841231200Smm
1842231200Smm    /* Keep existing table flag */
1843231200Smm    if (!rar_br_read_ahead(a, br, 1))
1844231200Smm      goto truncated_data;
1845231200Smm    if (!rar_br_bits(br, 1))
1846231200Smm      memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
1847231200Smm    rar_br_consume(br, 1);
1848231200Smm
1849231200Smm    memset(&bitlengths, 0, sizeof(bitlengths));
1850231200Smm    for (i = 0; i < MAX_SYMBOLS;)
1851231200Smm    {
1852231200Smm      if (!rar_br_read_ahead(a, br, 4))
1853231200Smm        goto truncated_data;
1854231200Smm      bitlengths[i++] = rar_br_bits(br, 4);
1855231200Smm      rar_br_consume(br, 4);
1856231200Smm      if (bitlengths[i-1] == 0xF)
1857231200Smm      {
1858231200Smm        if (!rar_br_read_ahead(a, br, 4))
1859231200Smm          goto truncated_data;
1860231200Smm        zerocount = rar_br_bits(br, 4);
1861231200Smm        rar_br_consume(br, 4);
1862231200Smm        if (zerocount)
1863231200Smm        {
1864231200Smm          i--;
1865231200Smm          for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++)
1866231200Smm            bitlengths[i++] = 0;
1867231200Smm        }
1868231200Smm      }
1869231200Smm    }
1870231200Smm
1871231200Smm    memset(&precode, 0, sizeof(precode));
1872231200Smm    r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH);
1873231200Smm    if (r != ARCHIVE_OK) {
1874231200Smm      free(precode.tree);
1875231200Smm      free(precode.table);
1876231200Smm      return (r);
1877231200Smm    }
1878231200Smm
1879231200Smm    for (i = 0; i < HUFFMAN_TABLE_SIZE;)
1880231200Smm    {
1881231200Smm      if ((val = read_next_symbol(a, &precode)) < 0) {
1882231200Smm        free(precode.tree);
1883231200Smm        free(precode.table);
1884231200Smm        return (ARCHIVE_FATAL);
1885231200Smm      }
1886231200Smm      if (val < 16)
1887231200Smm      {
1888231200Smm        rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF;
1889231200Smm        i++;
1890231200Smm      }
1891231200Smm      else if (val < 18)
1892231200Smm      {
1893231200Smm        if (i == 0)
1894231200Smm        {
1895231200Smm          free(precode.tree);
1896231200Smm          free(precode.table);
1897231200Smm          archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1898231200Smm                            "Internal error extracting RAR file.");
1899231200Smm          return (ARCHIVE_FATAL);
1900231200Smm        }
1901231200Smm
1902231200Smm        if(val == 16) {
1903231200Smm          if (!rar_br_read_ahead(a, br, 3)) {
1904231200Smm            free(precode.tree);
1905231200Smm            free(precode.table);
1906231200Smm            goto truncated_data;
1907231200Smm          }
1908231200Smm          n = rar_br_bits(br, 3) + 3;
1909231200Smm          rar_br_consume(br, 3);
1910231200Smm        } else {
1911231200Smm          if (!rar_br_read_ahead(a, br, 7)) {
1912231200Smm            free(precode.tree);
1913231200Smm            free(precode.table);
1914231200Smm            goto truncated_data;
1915231200Smm          }
1916231200Smm          n = rar_br_bits(br, 7) + 11;
1917231200Smm          rar_br_consume(br, 7);
1918231200Smm        }
1919231200Smm
1920231200Smm        for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++)
1921231200Smm        {
1922231200Smm          rar->lengthtable[i] = rar->lengthtable[i-1];
1923231200Smm          i++;
1924231200Smm        }
1925231200Smm      }
1926231200Smm      else
1927231200Smm      {
1928231200Smm        if(val == 18) {
1929231200Smm          if (!rar_br_read_ahead(a, br, 3)) {
1930231200Smm            free(precode.tree);
1931231200Smm            free(precode.table);
1932231200Smm            goto truncated_data;
1933231200Smm          }
1934231200Smm          n = rar_br_bits(br, 3) + 3;
1935231200Smm          rar_br_consume(br, 3);
1936231200Smm        } else {
1937231200Smm          if (!rar_br_read_ahead(a, br, 7)) {
1938231200Smm            free(precode.tree);
1939231200Smm            free(precode.table);
1940231200Smm            goto truncated_data;
1941231200Smm          }
1942231200Smm          n = rar_br_bits(br, 7) + 11;
1943231200Smm          rar_br_consume(br, 7);
1944231200Smm        }
1945231200Smm
1946231200Smm        for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++)
1947231200Smm          rar->lengthtable[i++] = 0;
1948231200Smm      }
1949231200Smm    }
1950231200Smm    free(precode.tree);
1951231200Smm    free(precode.table);
1952231200Smm
1953231200Smm    r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE,
1954231200Smm                MAX_SYMBOL_LENGTH);
1955231200Smm    if (r != ARCHIVE_OK)
1956231200Smm      return (r);
1957231200Smm    r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE],
1958231200Smm                OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH);
1959231200Smm    if (r != ARCHIVE_OK)
1960231200Smm      return (r);
1961231200Smm    r = create_code(a, &rar->lowoffsetcode,
1962231200Smm                &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE],
1963231200Smm                LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH);
1964231200Smm    if (r != ARCHIVE_OK)
1965231200Smm      return (r);
1966231200Smm    r = create_code(a, &rar->lengthcode,
1967231200Smm                &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE +
1968231200Smm                LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH);
1969231200Smm    if (r != ARCHIVE_OK)
1970231200Smm      return (r);
1971231200Smm  }
1972231200Smm
1973231200Smm  if (!rar->dictionary_size || !rar->lzss.window)
1974231200Smm  {
1975231200Smm    /* Seems as though dictionary sizes are not used. Even so, minimize
1976231200Smm     * memory usage as much as possible.
1977231200Smm     */
1978231200Smm    if (rar->unp_size >= DICTIONARY_MAX_SIZE)
1979231200Smm      rar->dictionary_size = DICTIONARY_MAX_SIZE;
1980231200Smm    else
1981231200Smm      rar->dictionary_size = rar_fls(rar->unp_size) << 1;
1982231200Smm    rar->lzss.window = (unsigned char *)realloc(rar->lzss.window,
1983231200Smm                                                rar->dictionary_size);
1984231200Smm    if (rar->lzss.window == NULL) {
1985231200Smm      archive_set_error(&a->archive, ENOMEM,
1986231200Smm                        "Unable to allocate memory for uncompressed data.");
1987231200Smm      return (ARCHIVE_FATAL);
1988231200Smm    }
1989231200Smm    memset(rar->lzss.window, 0, rar->dictionary_size);
1990231200Smm    rar->lzss.mask = rar->dictionary_size - 1;
1991231200Smm  }
1992231200Smm
1993231200Smm  rar->start_new_table = 0;
1994231200Smm  return (ARCHIVE_OK);
1995231200Smmtruncated_data:
1996231200Smm  archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1997231200Smm                    "Truncated RAR file data");
1998231200Smm  rar->valid = 0;
1999231200Smm  return (ARCHIVE_FATAL);
2000231200Smm}
2001231200Smm
2002231200Smmstatic void
2003231200Smmfree_codes(struct archive_read *a)
2004231200Smm{
2005231200Smm  struct rar *rar = (struct rar *)(a->format->data);
2006231200Smm  free(rar->maincode.tree);
2007231200Smm  free(rar->offsetcode.tree);
2008231200Smm  free(rar->lowoffsetcode.tree);
2009231200Smm  free(rar->lengthcode.tree);
2010231200Smm  free(rar->maincode.table);
2011231200Smm  free(rar->offsetcode.table);
2012231200Smm  free(rar->lowoffsetcode.table);
2013231200Smm  free(rar->lengthcode.table);
2014231200Smm  memset(&rar->maincode, 0, sizeof(rar->maincode));
2015231200Smm  memset(&rar->offsetcode, 0, sizeof(rar->offsetcode));
2016231200Smm  memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode));
2017231200Smm  memset(&rar->lengthcode, 0, sizeof(rar->lengthcode));
2018231200Smm}
2019231200Smm
2020231200Smm
2021231200Smmstatic int
2022231200Smmread_next_symbol(struct archive_read *a, struct huffman_code *code)
2023231200Smm{
2024231200Smm  unsigned char bit;
2025231200Smm  unsigned int bits;
2026231200Smm  int length, value, node;
2027231200Smm  struct rar *rar;
2028231200Smm  struct rar_br *br;
2029231200Smm
2030231200Smm  if (!code->table)
2031231200Smm  {
2032231200Smm    if (make_table(a, code) != (ARCHIVE_OK))
2033231200Smm      return -1;
2034231200Smm  }
2035231200Smm
2036231200Smm  rar = (struct rar *)(a->format->data);
2037231200Smm  br = &(rar->br);
2038231200Smm
2039231200Smm  /* Look ahead (peek) at bits */
2040231200Smm  if (!rar_br_read_ahead(a, br, code->tablesize)) {
2041231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2042231200Smm                      "Truncated RAR file data");
2043231200Smm    rar->valid = 0;
2044231200Smm    return -1;
2045231200Smm  }
2046231200Smm  bits = rar_br_bits(br, code->tablesize);
2047231200Smm
2048231200Smm  length = code->table[bits].length;
2049231200Smm  value = code->table[bits].value;
2050231200Smm
2051231200Smm  if (length < 0)
2052231200Smm  {
2053231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2054231200Smm                      "Invalid prefix code in bitstream");
2055231200Smm    return -1;
2056231200Smm  }
2057231200Smm
2058231200Smm  if (length <= code->tablesize)
2059231200Smm  {
2060231200Smm    /* Skip length bits */
2061231200Smm    rar_br_consume(br, length);
2062231200Smm    return value;
2063231200Smm  }
2064231200Smm
2065231200Smm  /* Skip tablesize bits */
2066231200Smm  rar_br_consume(br, code->tablesize);
2067231200Smm
2068231200Smm  node = value;
2069231200Smm  while (!(code->tree[node].branches[0] ==
2070231200Smm    code->tree[node].branches[1]))
2071231200Smm  {
2072231200Smm    if (!rar_br_read_ahead(a, br, 1)) {
2073231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2074231200Smm                        "Truncated RAR file data");
2075231200Smm      rar->valid = 0;
2076231200Smm      return -1;
2077231200Smm    }
2078231200Smm    bit = rar_br_bits(br, 1);
2079231200Smm    rar_br_consume(br, 1);
2080231200Smm
2081231200Smm    if (code->tree[node].branches[bit] < 0)
2082231200Smm    {
2083231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2084231200Smm                        "Invalid prefix code in bitstream");
2085231200Smm      return -1;
2086231200Smm    }
2087231200Smm    node = code->tree[node].branches[bit];
2088231200Smm  }
2089231200Smm
2090231200Smm  return code->tree[node].branches[0];
2091231200Smm}
2092231200Smm
2093231200Smmstatic int
2094231200Smmcreate_code(struct archive_read *a, struct huffman_code *code,
2095231200Smm            unsigned char *lengths, int numsymbols, char maxlength)
2096231200Smm{
2097231200Smm  int i, j, codebits = 0, symbolsleft = numsymbols;
2098231200Smm
2099231200Smm  if (new_node(code) < 0) {
2100231200Smm    archive_set_error(&a->archive, ENOMEM,
2101231200Smm                      "Unable to allocate memory for node data.");
2102231200Smm    return (ARCHIVE_FATAL);
2103231200Smm  }
2104231200Smm  code->numentries = 1;
2105231200Smm  code->minlength = INT_MAX;
2106231200Smm  code->maxlength = INT_MIN;
2107231200Smm  codebits = 0;
2108231200Smm  for(i = 1; i <= maxlength; i++)
2109231200Smm  {
2110231200Smm    for(j = 0; j < numsymbols; j++)
2111231200Smm    {
2112231200Smm      if (lengths[j] != i) continue;
2113231200Smm      if (add_value(a, code, j, codebits, i) != ARCHIVE_OK)
2114231200Smm        return (ARCHIVE_FATAL);
2115231200Smm      codebits++;
2116231200Smm      if (--symbolsleft <= 0) { break; break; }
2117231200Smm    }
2118231200Smm    codebits <<= 1;
2119231200Smm  }
2120231200Smm  return (ARCHIVE_OK);
2121231200Smm}
2122231200Smm
2123231200Smmstatic int
2124231200Smmadd_value(struct archive_read *a, struct huffman_code *code, int value,
2125231200Smm          int codebits, int length)
2126231200Smm{
2127231200Smm  int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode;
2128231200Smm
2129231200Smm  free(code->table);
2130231200Smm  code->table = NULL;
2131231200Smm
2132231200Smm  if(length > code->maxlength)
2133231200Smm    code->maxlength = length;
2134231200Smm  if(length < code->minlength)
2135231200Smm    code->minlength = length;
2136231200Smm
2137231200Smm  repeatpos = -1;
2138231200Smm  if (repeatpos == 0 || (repeatpos >= 0
2139231200Smm    && (((codebits >> (repeatpos - 1)) & 3) == 0
2140231200Smm    || ((codebits >> (repeatpos - 1)) & 3) == 3)))
2141231200Smm  {
2142231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2143231200Smm                      "Invalid repeat position");
2144231200Smm    return (ARCHIVE_FATAL);
2145231200Smm  }
2146231200Smm
2147231200Smm  lastnode = 0;
2148231200Smm  for (bitpos = length - 1; bitpos >= 0; bitpos--)
2149231200Smm  {
2150231200Smm    bit = (codebits >> bitpos) & 1;
2151231200Smm
2152231200Smm    /* Leaf node check */
2153231200Smm    if (code->tree[lastnode].branches[0] ==
2154231200Smm      code->tree[lastnode].branches[1])
2155231200Smm    {
2156231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2157231200Smm                        "Prefix found");
2158231200Smm      return (ARCHIVE_FATAL);
2159231200Smm    }
2160231200Smm
2161231200Smm    if (bitpos == repeatpos)
2162231200Smm    {
2163231200Smm      /* Open branch check */
2164231200Smm      if (!(code->tree[lastnode].branches[bit] < 0))
2165231200Smm      {
2166231200Smm        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2167231200Smm                          "Invalid repeating code");
2168231200Smm        return (ARCHIVE_FATAL);
2169231200Smm      }
2170231200Smm
2171231200Smm      if ((repeatnode = new_node(code)) < 0) {
2172231200Smm        archive_set_error(&a->archive, ENOMEM,
2173231200Smm                          "Unable to allocate memory for node data.");
2174231200Smm        return (ARCHIVE_FATAL);
2175231200Smm      }
2176231200Smm      if ((nextnode = new_node(code)) < 0) {
2177231200Smm        archive_set_error(&a->archive, ENOMEM,
2178231200Smm                          "Unable to allocate memory for node data.");
2179231200Smm        return (ARCHIVE_FATAL);
2180231200Smm      }
2181231200Smm
2182231200Smm      /* Set branches */
2183231200Smm      code->tree[lastnode].branches[bit] = repeatnode;
2184231200Smm      code->tree[repeatnode].branches[bit] = repeatnode;
2185231200Smm      code->tree[repeatnode].branches[bit^1] = nextnode;
2186231200Smm      lastnode = nextnode;
2187231200Smm
2188231200Smm      bitpos++; /* terminating bit already handled, skip it */
2189231200Smm    }
2190231200Smm    else
2191231200Smm    {
2192231200Smm      /* Open branch check */
2193231200Smm      if (code->tree[lastnode].branches[bit] < 0)
2194231200Smm      {
2195231200Smm        if (new_node(code) < 0) {
2196231200Smm          archive_set_error(&a->archive, ENOMEM,
2197231200Smm                            "Unable to allocate memory for node data.");
2198231200Smm          return (ARCHIVE_FATAL);
2199231200Smm        }
2200231200Smm        code->tree[lastnode].branches[bit] = code->numentries++;
2201231200Smm      }
2202231200Smm
2203231200Smm      /* set to branch */
2204231200Smm      lastnode = code->tree[lastnode].branches[bit];
2205231200Smm    }
2206231200Smm  }
2207231200Smm
2208231200Smm  if (!(code->tree[lastnode].branches[0] == -1
2209231200Smm    && code->tree[lastnode].branches[1] == -2))
2210231200Smm  {
2211231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2212231200Smm                      "Prefix found");
2213231200Smm    return (ARCHIVE_FATAL);
2214231200Smm  }
2215231200Smm
2216231200Smm  /* Set leaf value */
2217231200Smm  code->tree[lastnode].branches[0] = value;
2218231200Smm  code->tree[lastnode].branches[1] = value;
2219231200Smm
2220231200Smm  return (ARCHIVE_OK);
2221231200Smm}
2222231200Smm
2223231200Smmstatic int
2224231200Smmnew_node(struct huffman_code *code)
2225231200Smm{
2226231200Smm  code->tree = (struct huffman_tree_node *)realloc(code->tree,
2227231200Smm    (code->numentries + 1) * sizeof(*code->tree));
2228231200Smm  if (code->tree == NULL)
2229231200Smm    return (-1);
2230231200Smm  code->tree[code->numentries].branches[0] = -1;
2231231200Smm  code->tree[code->numentries].branches[1] = -2;
2232231200Smm  return 1;
2233231200Smm}
2234231200Smm
2235231200Smmstatic int
2236231200Smmmake_table(struct archive_read *a, struct huffman_code *code)
2237231200Smm{
2238231200Smm  if (code->maxlength < code->minlength || code->maxlength > 10)
2239231200Smm    code->tablesize = 10;
2240231200Smm  else
2241231200Smm    code->tablesize = code->maxlength;
2242231200Smm
2243231200Smm  code->table =
2244231200Smm    (struct huffman_table_entry *)malloc(sizeof(*code->table)
2245231200Smm    * (1 << code->tablesize));
2246231200Smm
2247231200Smm  return make_table_recurse(a, code, 0, code->table, 0, code->tablesize);
2248231200Smm}
2249231200Smm
2250231200Smmstatic int
2251231200Smmmake_table_recurse(struct archive_read *a, struct huffman_code *code, int node,
2252231200Smm                   struct huffman_table_entry *table, int depth,
2253231200Smm                   int maxdepth)
2254231200Smm{
2255231200Smm  int currtablesize, i, ret = (ARCHIVE_OK);
2256231200Smm
2257231200Smm  if (!code->tree)
2258231200Smm  {
2259231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2260231200Smm                      "Huffman tree was not created.");
2261231200Smm    return (ARCHIVE_FATAL);
2262231200Smm  }
2263231200Smm  if (node < 0 || node >= code->numentries)
2264231200Smm  {
2265231200Smm    archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2266231200Smm                      "Invalid location to Huffman tree specified.");
2267231200Smm    return (ARCHIVE_FATAL);
2268231200Smm  }
2269231200Smm
2270231200Smm  currtablesize = 1 << (maxdepth - depth);
2271231200Smm
2272231200Smm  if (code->tree[node].branches[0] ==
2273231200Smm    code->tree[node].branches[1])
2274231200Smm  {
2275231200Smm    for(i = 0; i < currtablesize; i++)
2276231200Smm    {
2277231200Smm      table[i].length = depth;
2278231200Smm      table[i].value = code->tree[node].branches[0];
2279231200Smm    }
2280231200Smm  }
2281231200Smm  else if (node < 0)
2282231200Smm  {
2283231200Smm    for(i = 0; i < currtablesize; i++)
2284231200Smm      table[i].length = -1;
2285231200Smm  }
2286231200Smm  else
2287231200Smm  {
2288231200Smm    if(depth == maxdepth)
2289231200Smm    {
2290231200Smm      table[0].length = maxdepth + 1;
2291231200Smm      table[0].value = node;
2292231200Smm    }
2293231200Smm    else
2294231200Smm    {
2295231200Smm      ret |= make_table_recurse(a, code, code->tree[node].branches[0], table,
2296231200Smm                                depth + 1, maxdepth);
2297231200Smm      ret |= make_table_recurse(a, code, code->tree[node].branches[1],
2298231200Smm                         table + currtablesize / 2, depth + 1, maxdepth);
2299231200Smm    }
2300231200Smm  }
2301231200Smm  return ret;
2302231200Smm}
2303231200Smm
2304231200Smmstatic int64_t
2305231200Smmexpand(struct archive_read *a, int64_t end)
2306231200Smm{
2307231200Smm  static const unsigned char lengthbases[] =
2308231200Smm    {   0,   1,   2,   3,   4,   5,   6,
2309231200Smm        7,   8,  10,  12,  14,  16,  20,
2310231200Smm       24,  28,  32,  40,  48,  56,  64,
2311231200Smm       80,  96, 112, 128, 160, 192, 224 };
2312231200Smm  static const unsigned char lengthbits[] =
2313231200Smm    { 0, 0, 0, 0, 0, 0, 0,
2314231200Smm      0, 1, 1, 1, 1, 2, 2,
2315231200Smm      2, 2, 3, 3, 3, 3, 4,
2316231200Smm      4, 4, 4, 5, 5, 5, 5 };
2317231200Smm  static const unsigned int offsetbases[] =
2318231200Smm    {       0,       1,       2,       3,       4,       6,
2319231200Smm            8,      12,      16,      24,      32,      48,
2320231200Smm           64,      96,     128,     192,     256,     384,
2321231200Smm          512,     768,    1024,    1536,    2048,    3072,
2322231200Smm         4096,    6144,    8192,   12288,   16384,   24576,
2323231200Smm        32768,   49152,   65536,   98304,  131072,  196608,
2324231200Smm       262144,  327680,  393216,  458752,  524288,  589824,
2325231200Smm       655360,  720896,  786432,  851968,  917504,  983040,
2326231200Smm      1048576, 1310720, 1572864, 1835008, 2097152, 2359296,
2327231200Smm      2621440, 2883584, 3145728, 3407872, 3670016, 3932160 };
2328231200Smm  static const unsigned char offsetbits[] =
2329231200Smm    {  0,  0,  0,  0,  1,  1,  2,  2,  3,  3,  4,  4,
2330231200Smm       5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10,
2331231200Smm      11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
2332231200Smm      16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2333231200Smm      18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 };
2334231200Smm  static const unsigned char shortbases[] =
2335231200Smm    { 0, 4, 8, 16, 32, 64, 128, 192 };
2336231200Smm  static const unsigned char shortbits[] =
2337231200Smm    { 2, 2, 3, 4, 5, 6, 6, 6 };
2338231200Smm
2339231200Smm  int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol;
2340231200Smm  unsigned char newfile;
2341231200Smm  struct rar *rar = (struct rar *)(a->format->data);
2342231200Smm  struct rar_br *br = &(rar->br);
2343231200Smm
2344231200Smm  if (rar->filterstart < end)
2345231200Smm    end = rar->filterstart;
2346231200Smm
2347231200Smm  while (1)
2348231200Smm  {
2349231200Smm    if (rar->output_last_match &&
2350231200Smm      lzss_position(&rar->lzss) + rar->lastlength <= end)
2351231200Smm    {
2352231200Smm      lzss_emit_match(rar, rar->lastoffset, rar->lastlength);
2353231200Smm      rar->output_last_match = 0;
2354231200Smm    }
2355231200Smm
2356231200Smm    if(rar->is_ppmd_block || rar->output_last_match ||
2357231200Smm      lzss_position(&rar->lzss) >= end)
2358231200Smm      return lzss_position(&rar->lzss);
2359231200Smm
2360231200Smm    if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
2361231200Smm      return (ARCHIVE_FATAL);
2362231200Smm    rar->output_last_match = 0;
2363231200Smm
2364231200Smm    if (symbol < 256)
2365231200Smm    {
2366231200Smm      lzss_emit_literal(rar, symbol);
2367231200Smm      continue;
2368231200Smm    }
2369231200Smm    else if (symbol == 256)
2370231200Smm    {
2371231200Smm      if (!rar_br_read_ahead(a, br, 1))
2372231200Smm        goto truncated_data;
2373231200Smm      newfile = !rar_br_bits(br, 1);
2374231200Smm      rar_br_consume(br, 1);
2375231200Smm
2376231200Smm      if(newfile)
2377231200Smm      {
2378231200Smm        rar->start_new_block = 1;
2379231200Smm        if (!rar_br_read_ahead(a, br, 1))
2380231200Smm          goto truncated_data;
2381231200Smm        rar->start_new_table = rar_br_bits(br, 1);
2382231200Smm        rar_br_consume(br, 1);
2383231200Smm        return lzss_position(&rar->lzss);
2384231200Smm      }
2385231200Smm      else
2386231200Smm      {
2387231200Smm        if (parse_codes(a) != ARCHIVE_OK)
2388231200Smm          return (ARCHIVE_FATAL);
2389231200Smm        continue;
2390231200Smm      }
2391231200Smm    }
2392231200Smm    else if(symbol==257)
2393231200Smm    {
2394231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2395231200Smm                        "Parsing filters is unsupported.");
2396231200Smm      return (ARCHIVE_FAILED);
2397231200Smm    }
2398231200Smm    else if(symbol==258)
2399231200Smm    {
2400231200Smm      if(rar->lastlength == 0)
2401231200Smm        continue;
2402231200Smm
2403231200Smm      offs = rar->lastoffset;
2404231200Smm      len = rar->lastlength;
2405231200Smm    }
2406231200Smm    else if (symbol <= 262)
2407231200Smm    {
2408231200Smm      offsindex = symbol - 259;
2409231200Smm      offs = rar->oldoffset[offsindex];
2410231200Smm
2411231200Smm      if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
2412231200Smm        goto bad_data;
2413232153Smm      if (lensymbol > (int)(sizeof(lengthbases)/sizeof(lengthbases[0])))
2414231200Smm        goto bad_data;
2415232153Smm      if (lensymbol > (int)(sizeof(lengthbits)/sizeof(lengthbits[0])))
2416231200Smm        goto bad_data;
2417231200Smm      len = lengthbases[lensymbol] + 2;
2418231200Smm      if (lengthbits[lensymbol] > 0) {
2419231200Smm        if (!rar_br_read_ahead(a, br, lengthbits[lensymbol]))
2420231200Smm          goto truncated_data;
2421231200Smm        len += rar_br_bits(br, lengthbits[lensymbol]);
2422231200Smm        rar_br_consume(br, lengthbits[lensymbol]);
2423231200Smm      }
2424231200Smm
2425231200Smm      for (i = offsindex; i > 0; i--)
2426231200Smm        rar->oldoffset[i] = rar->oldoffset[i-1];
2427231200Smm      rar->oldoffset[0] = offs;
2428231200Smm    }
2429231200Smm    else if(symbol<=270)
2430231200Smm    {
2431231200Smm      offs = shortbases[symbol-263] + 1;
2432231200Smm      if(shortbits[symbol-263] > 0) {
2433231200Smm        if (!rar_br_read_ahead(a, br, shortbits[symbol-263]))
2434231200Smm          goto truncated_data;
2435231200Smm        offs += rar_br_bits(br, shortbits[symbol-263]);
2436231200Smm        rar_br_consume(br, shortbits[symbol-263]);
2437231200Smm      }
2438231200Smm
2439231200Smm      len = 2;
2440231200Smm
2441231200Smm      for(i = 3; i > 0; i--)
2442231200Smm        rar->oldoffset[i] = rar->oldoffset[i-1];
2443231200Smm      rar->oldoffset[0] = offs;
2444231200Smm    }
2445231200Smm    else
2446231200Smm    {
2447232153Smm      if (symbol-271 > (int)(sizeof(lengthbases)/sizeof(lengthbases[0])))
2448231200Smm        goto bad_data;
2449232153Smm      if (symbol-271 > (int)(sizeof(lengthbits)/sizeof(lengthbits[0])))
2450231200Smm        goto bad_data;
2451231200Smm      len = lengthbases[symbol-271]+3;
2452231200Smm      if(lengthbits[symbol-271] > 0) {
2453231200Smm        if (!rar_br_read_ahead(a, br, lengthbits[symbol-271]))
2454231200Smm          goto truncated_data;
2455231200Smm        len += rar_br_bits(br, lengthbits[symbol-271]);
2456231200Smm        rar_br_consume(br, lengthbits[symbol-271]);
2457231200Smm      }
2458231200Smm
2459231200Smm      if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
2460231200Smm        goto bad_data;
2461232153Smm      if (offssymbol > (int)(sizeof(offsetbases)/sizeof(offsetbases[0])))
2462231200Smm        goto bad_data;
2463232153Smm      if (offssymbol > (int)(sizeof(offsetbits)/sizeof(offsetbits[0])))
2464231200Smm        goto bad_data;
2465231200Smm      offs = offsetbases[offssymbol]+1;
2466231200Smm      if(offsetbits[offssymbol] > 0)
2467231200Smm      {
2468231200Smm        if(offssymbol > 9)
2469231200Smm        {
2470231200Smm          if(offsetbits[offssymbol] > 4) {
2471231200Smm            if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4))
2472231200Smm              goto truncated_data;
2473231200Smm            offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4;
2474231200Smm            rar_br_consume(br, offsetbits[offssymbol] - 4);
2475231200Smm	  }
2476231200Smm
2477231200Smm          if(rar->numlowoffsetrepeats > 0)
2478231200Smm          {
2479231200Smm            rar->numlowoffsetrepeats--;
2480231200Smm            offs += rar->lastlowoffset;
2481231200Smm          }
2482231200Smm          else
2483231200Smm          {
2484231200Smm            if ((lowoffsetsymbol =
2485231200Smm              read_next_symbol(a, &rar->lowoffsetcode)) < 0)
2486231200Smm              return (ARCHIVE_FATAL);
2487231200Smm            if(lowoffsetsymbol == 16)
2488231200Smm            {
2489231200Smm              rar->numlowoffsetrepeats = 15;
2490231200Smm              offs += rar->lastlowoffset;
2491231200Smm            }
2492231200Smm            else
2493231200Smm            {
2494231200Smm              offs += lowoffsetsymbol;
2495231200Smm              rar->lastlowoffset = lowoffsetsymbol;
2496231200Smm            }
2497231200Smm          }
2498231200Smm        }
2499231200Smm        else {
2500231200Smm          if (!rar_br_read_ahead(a, br, offsetbits[offssymbol]))
2501231200Smm            goto truncated_data;
2502231200Smm          offs += rar_br_bits(br, offsetbits[offssymbol]);
2503231200Smm          rar_br_consume(br, offsetbits[offssymbol]);
2504231200Smm        }
2505231200Smm      }
2506231200Smm
2507231200Smm      if (offs >= 0x40000)
2508231200Smm        len++;
2509231200Smm      if (offs >= 0x2000)
2510231200Smm        len++;
2511231200Smm
2512231200Smm      for(i = 3; i > 0; i--)
2513231200Smm        rar->oldoffset[i] = rar->oldoffset[i-1];
2514231200Smm      rar->oldoffset[0] = offs;
2515231200Smm    }
2516231200Smm
2517231200Smm    rar->lastoffset = offs;
2518231200Smm    rar->lastlength = len;
2519231200Smm    rar->output_last_match = 1;
2520231200Smm  }
2521231200Smmtruncated_data:
2522231200Smm  archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2523231200Smm                    "Truncated RAR file data");
2524231200Smm  rar->valid = 0;
2525231200Smm  return (ARCHIVE_FATAL);
2526231200Smmbad_data:
2527231200Smm  archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2528231200Smm                    "Bad RAR file data");
2529231200Smm  return (ARCHIVE_FATAL);
2530231200Smm}
2531231200Smm
2532231200Smmstatic int
2533231200Smmcopy_from_lzss_window(struct archive_read *a, const void **buffer,
2534231200Smm                        int64_t startpos, int length)
2535231200Smm{
2536231200Smm  int windowoffs, firstpart;
2537231200Smm  struct rar *rar = (struct rar *)(a->format->data);
2538231200Smm
2539231200Smm  if (!rar->unp_buffer)
2540231200Smm  {
2541231200Smm    if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
2542231200Smm    {
2543231200Smm      archive_set_error(&a->archive, ENOMEM,
2544231200Smm                        "Unable to allocate memory for uncompressed data.");
2545231200Smm      return (ARCHIVE_FATAL);
2546231200Smm    }
2547231200Smm  }
2548231200Smm
2549231200Smm  windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
2550231200Smm  if(windowoffs + length <= lzss_size(&rar->lzss))
2551231200Smm    memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
2552231200Smm           length);
2553231200Smm  else
2554231200Smm  {
2555231200Smm    firstpart = lzss_size(&rar->lzss) - windowoffs;
2556231200Smm    if (firstpart < 0) {
2557231200Smm      archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2558231200Smm                        "Bad RAR file data");
2559231200Smm      return (ARCHIVE_FATAL);
2560231200Smm    }
2561231200Smm    if (firstpart < length) {
2562231200Smm      memcpy(&rar->unp_buffer[rar->unp_offset],
2563231200Smm             &rar->lzss.window[windowoffs], firstpart);
2564231200Smm      memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
2565231200Smm             &rar->lzss.window[0], length - firstpart);
2566231200Smm    } else
2567231200Smm      memcpy(&rar->unp_buffer[rar->unp_offset],
2568231200Smm             &rar->lzss.window[windowoffs], length);
2569231200Smm  }
2570231200Smm  rar->unp_offset += length;
2571231200Smm  if (rar->unp_offset >= rar->unp_buffer_size)
2572231200Smm    *buffer = rar->unp_buffer;
2573231200Smm  else
2574231200Smm    *buffer = NULL;
2575231200Smm  return (ARCHIVE_OK);
2576231200Smm}
2577