Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
rar.h File Reference
#include "../common/unarr-imp.h"
#include "lzss.h"
#include "../lzmasdk/Ppmd7.h"
#include <limits.h>
+ Include dependency graph for rar.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  rar_header
 
struct  rar_entry
 
struct  ar_archive_rar_entry
 
struct  ar_archive_rar_filters
 
struct  huffman_code
 
struct  ByteReader
 
struct  CPpmdRAR_RangeDec
 
struct  ar_archive_rar_uncomp_v3
 
struct  AudioState
 
struct  ar_archive_rar_uncomp_v2
 
struct  ar_archive_rar_uncomp
 
struct  ar_archive_rar_uncomp::StreamBitReader
 
struct  ar_archive_rar_progress
 
struct  ar_archive_rar_solid
 
struct  ar_archive_rar_s
 

Macros

#define FILE_SIGNATURE_SIZE   7
 
#define LZSS_WINDOW_SIZE   0x400000
 
#define LZSS_OVERFLOW_SIZE   288
 
#define MAINCODE_SIZE   299
 
#define OFFSETCODE_SIZE   60
 
#define LOWOFFSETCODE_SIZE   17
 
#define LENGTHCODE_SIZE   28
 
#define HUFFMAN_TABLE_SIZE   MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE + LENGTHCODE_SIZE
 
#define MAINCODE_SIZE_20   298
 
#define OFFSETCODE_SIZE_20   48
 
#define LENGTHCODE_SIZE_20   28
 
#define HUFFMAN_TABLE_SIZE_20   4 * 257
 

Typedefs

typedef struct ar_archive_rar_s ar_archive_rar
 

Enumerations

enum  block_types {
  TYPE_FILE_SIGNATURE = 0x72, TYPE_MAIN_HEADER = 0x73, TYPE_FILE_ENTRY = 0x74, TYPE_NEWSUB = 0x7A,
  TYPE_END_OF_ARCHIVE = 0x7B
}
 
enum  archive_flags {
  MHD_VOLUME = 1 << 0, MHD_COMMENT = 1 << 1, MHD_LOCK = 1 << 2, MHD_SOLID = 1 << 3,
  MHD_PACK_COMMENT = 1 << 4, MHD_AV = 1 << 5, MHD_PROTECT = 1 << 6, MHD_PASSWORD = 1 << 7,
  MHD_FIRSTVOLUME = 1 << 8, MHD_ENCRYPTVER = 1 << 9, MHD_LONG_BLOCK = 1 << 15
}
 
enum  entry_flags {
  LHD_SPLIT_BEFORE = 1 << 0, LHD_SPLIT_AFTER = 1 << 1, LHD_PASSWORD = 1 << 2, LHD_COMMENT = 1 << 3,
  LHD_SOLID = 1 << 4, LHD_DIRECTORY = (1 << 5) | (1 << 6) | (1 << 7), LHD_LARGE = 1 << 8, LHD_UNICODE = 1 << 9,
  LHD_SALT = 1 << 10, LHD_VERSION = 1 << 11, LHD_EXTTIME = 1 << 12, LHD_EXTFLAGS = 1 << 13,
  LHD_LONG_BLOCK = 1 << 15
}
 
enum  compression_method {
  METHOD_STORE = 0x30, METHOD_FASTEST = 0x31, METHOD_FAST = 0x32, METHOD_NORMAL = 0x33,
  METHOD_GOOD = 0x34, METHOD_BEST = 0x35
}
 

Functions

static size_t smin (size_t a, size_t b)
 
bool rar_parse_header (ar_archive *ar, struct rar_header *header)
 
bool rar_check_header_crc (ar_archive *ar)
 
bool rar_parse_header_entry (ar_archive_rar *rar, struct rar_header *header, struct rar_entry *entry)
 
const char * rar_get_name (ar_archive *ar)
 
bool rar_parse_filter (ar_archive_rar *rar, const uint8_t *bytes, uint16_t length, uint8_t flags)
 
bool rar_run_filters (ar_archive_rar *rar)
 
void rar_clear_filters (struct ar_archive_rar_filters *filters)
 
bool rar_new_node (struct huffman_code *code)
 
bool rar_add_value (struct huffman_code *code, int value, int codebits, int length)
 
bool rar_create_code (struct huffman_code *code, uint8_t *lengths, int numsymbols)
 
bool rar_make_table (struct huffman_code *code)
 
void rar_free_code (struct huffman_code *code)
 
static bool rar_is_leaf_node (struct huffman_code *code, int node)
 
bool rar_uncompress_part (ar_archive_rar *rar, void *buffer, size_t buffer_size)
 
int64_t rar_expand (ar_archive_rar *rar, int64_t end)
 
void rar_clear_uncompress (struct ar_archive_rar_uncomp *uncomp)
 
static void br_clear_leftover_bits (struct ar_archive_rar_uncomp *uncomp)
 

Macro Definition Documentation

#define FILE_SIGNATURE_SIZE   7

Definition at line 19 of file rar.h.

#define HUFFMAN_TABLE_SIZE   MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE + LENGTHCODE_SIZE

Definition at line 137 of file rar.h.

#define HUFFMAN_TABLE_SIZE_20   4 * 257

Definition at line 176 of file rar.h.

#define LENGTHCODE_SIZE   28

Definition at line 136 of file rar.h.

#define LENGTHCODE_SIZE_20   28

Definition at line 175 of file rar.h.

#define LOWOFFSETCODE_SIZE   17

Definition at line 135 of file rar.h.

#define LZSS_OVERFLOW_SIZE   288

Definition at line 131 of file rar.h.

#define LZSS_WINDOW_SIZE   0x400000

Definition at line 130 of file rar.h.

#define MAINCODE_SIZE   299

Definition at line 133 of file rar.h.

#define MAINCODE_SIZE_20   298

Definition at line 173 of file rar.h.

#define OFFSETCODE_SIZE   60

Definition at line 134 of file rar.h.

#define OFFSETCODE_SIZE_20   48

Definition at line 174 of file rar.h.

Typedef Documentation

Definition at line 15 of file rar.h.

Enumeration Type Documentation

Enumerator
MHD_VOLUME 
MHD_COMMENT 
MHD_LOCK 
MHD_SOLID 
MHD_PACK_COMMENT 
MHD_AV 
MHD_PROTECT 
MHD_PASSWORD 
MHD_FIRSTVOLUME 
MHD_ENCRYPTVER 
MHD_LONG_BLOCK 

Definition at line 26 of file rar.h.

26  {
27  MHD_VOLUME = 1 << 0, MHD_COMMENT = 1 << 1, MHD_LOCK = 1 << 2,
28  MHD_SOLID = 1 << 3, MHD_PACK_COMMENT = 1 << 4, MHD_AV = 1 << 5,
29  MHD_PROTECT = 1 << 6, MHD_PASSWORD = 1 << 7, MHD_FIRSTVOLUME = 1 << 8,
30  MHD_ENCRYPTVER = 1 << 9,
31  MHD_LONG_BLOCK = 1 << 15,
32 };
Enumerator
TYPE_FILE_SIGNATURE 
TYPE_MAIN_HEADER 
TYPE_FILE_ENTRY 
TYPE_NEWSUB 
TYPE_END_OF_ARCHIVE 

Definition at line 21 of file rar.h.

21  {
23  TYPE_NEWSUB = 0x7A, TYPE_END_OF_ARCHIVE = 0x7B,
24 };
Enumerator
METHOD_STORE 
METHOD_FASTEST 
METHOD_FAST 
METHOD_NORMAL 
METHOD_GOOD 
METHOD_BEST 

Definition at line 43 of file rar.h.

43  {
44  METHOD_STORE = 0x30,
45  METHOD_FASTEST = 0x31, METHOD_FAST = 0x32, METHOD_NORMAL = 0x33,
46  METHOD_GOOD = 0x34, METHOD_BEST = 0x35,
47 };
Enumerator
LHD_SPLIT_BEFORE 
LHD_SPLIT_AFTER 
LHD_PASSWORD 
LHD_COMMENT 
LHD_SOLID 
LHD_DIRECTORY 
LHD_LARGE 
LHD_UNICODE 
LHD_SALT 
LHD_VERSION 
LHD_EXTTIME 
LHD_EXTFLAGS 
LHD_LONG_BLOCK 

Definition at line 34 of file rar.h.

34  {
35  LHD_SPLIT_BEFORE = 1 << 0, LHD_SPLIT_AFTER = 1 << 1, LHD_PASSWORD = 1 << 2,
36  LHD_COMMENT = 1 << 3, LHD_SOLID = 1 << 4,
37  LHD_DIRECTORY = (1 << 5) | (1 << 6) | (1 << 7),
38  LHD_LARGE = 1 << 8, LHD_UNICODE = 1 << 9, LHD_SALT = 1 << 10,
39  LHD_VERSION = 1 << 11, LHD_EXTTIME = 1 << 12, LHD_EXTFLAGS = 1 << 13,
40  LHD_LONG_BLOCK = 1 << 15,
41 };

Function Documentation

static void br_clear_leftover_bits ( struct ar_archive_rar_uncomp uncomp)
inlinestatic

Definition at line 227 of file rar.h.

227 { uncomp->br.available &= ~0x07; }

+ Here is the caller graph for this function:

bool rar_add_value ( struct huffman_code code,
int  value,
int  codebits,
int  length 
)

Definition at line 33 of file huffman-rar.c.

34 {
35  int lastnode, bitpos, bit;
36 
37  free(code->table);
38  code->table = NULL;
39 
40  if (length > code->maxlength)
41  code->maxlength = length;
42  if (length < code->minlength)
43  code->minlength = length;
44 
45  lastnode = 0;
46  for (bitpos = length - 1; bitpos >= 0; bitpos--) {
47  bit = (codebits >> bitpos) & 1;
48  if (rar_is_leaf_node(code, lastnode)) {
49  warn("Invalid data in bitstream"); /* prefix found */
50  return false;
51  }
52  if (code->tree[lastnode].branches[bit] < 0) {
53  if (!rar_new_node(code))
54  return false;
55  code->tree[lastnode].branches[bit] = code->numentries - 1;
56  }
57  lastnode = code->tree[lastnode].branches[bit];
58  }
59 
60  if (code->tree[lastnode].branches[0] != -1 || code->tree[lastnode].branches[1] != -2) {
61  warn("Invalid data in bitstream"); /* prefix found */
62  return false;
63  }
64  code->tree[lastnode].branches[0] = code->tree[lastnode].branches[1] = value;
65  return true;
66 }

+ Here is the caller graph for this function:

bool rar_check_header_crc ( ar_archive ar)

Definition at line 47 of file parse-rar.c.

48 {
49  unsigned char buffer[256];
50  uint16_t crc16, size;
51  uint32_t crc32;
52 
53  if (!ar_seek(ar->stream, ar->entry_offset, SEEK_SET))
54  return false;
55  if (ar_read(ar->stream, buffer, 7) != 7)
56  return false;
57 
58  crc16 = uint16le(buffer + 0);
59  size = uint16le(buffer + 5);
60  if (size < 7)
61  return false;
62  size -= 7;
63 
64  crc32 = ar_crc32(0, buffer + 2, 5);
65  while (size > 0) {
66  if (ar_read(ar->stream, buffer, smin(size, sizeof(buffer))) != smin(size, sizeof(buffer)))
67  return false;
68  crc32 = ar_crc32(crc32, buffer, smin(size, sizeof(buffer)));
69  size -= (uint16_t)smin(size, sizeof(buffer));
70  }
71  return (crc32 & 0xFFFF) == crc16;
72 }

+ Here is the caller graph for this function:

void rar_clear_filters ( struct ar_archive_rar_filters filters)

Definition at line 699 of file filter-rar.c.

700 {
701  rar_delete_filter(filters->stack);
702  rar_delete_program(filters->progs);
703  free(filters->vm);
704 }

+ Here is the caller graph for this function:

void rar_clear_uncompress ( struct ar_archive_rar_uncomp uncomp)

Definition at line 148 of file uncompress-rar.c.

149 {
150  if (!uncomp->version)
151  return;
152  rar_free_codes(uncomp);
153  lzss_cleanup(&uncomp->lzss);
154  if (uncomp->version == 3) {
156  rar_clear_filters(&uncomp->state.v3.filters);
157  }
158  uncomp->version = 0;
159 }

+ Here is the caller graph for this function:

bool rar_create_code ( struct huffman_code code,
uint8_t *  lengths,
int  numsymbols 
)

Definition at line 68 of file huffman-rar.c.

69 {
70  int symbolsleft = numsymbols;
71  int codebits = 0;
72  int i, j;
73 
74  if (!rar_new_node(code))
75  return false;
76 
77  for (i = 1; i <= 0x0F; i++) {
78  for (j = 0; j < numsymbols; j++) {
79  if (lengths[j] != i)
80  continue;
81  if (!rar_add_value(code, j, codebits, i))
82  return false;
83  if (--symbolsleft <= 0)
84  return true;
85  codebits++;
86  }
87  codebits <<= 1;
88  }
89  return true;
90 }

+ Here is the caller graph for this function:

int64_t rar_expand ( ar_archive_rar rar,
int64_t  end 
)

Definition at line 795 of file uncompress-rar.c.

796 {
797  static const uint8_t lengthbases[] =
798  { 0, 1, 2, 3, 4, 5, 6,
799  7, 8, 10, 12, 14, 16, 20,
800  24, 28, 32, 40, 48, 56, 64,
801  80, 96, 112, 128, 160, 192, 224 };
802  static const uint8_t lengthbits[] =
803  { 0, 0, 0, 0, 0, 0, 0,
804  0, 1, 1, 1, 1, 2, 2,
805  2, 2, 3, 3, 3, 3, 4,
806  4, 4, 4, 5, 5, 5, 5 };
807  static const int32_t offsetbases[] =
808  { 0, 1, 2, 3, 4, 6,
809  8, 12, 16, 24, 32, 48,
810  64, 96, 128, 192, 256, 384,
811  512, 768, 1024, 1536, 2048, 3072,
812  4096, 6144, 8192, 12288, 16384, 24576,
813  32768, 49152, 65536, 98304, 131072, 196608,
814  262144, 327680, 393216, 458752, 524288, 589824,
815  655360, 720896, 786432, 851968, 917504, 983040,
816  1048576, 1310720, 1572864, 1835008, 2097152, 2359296,
817  2621440, 2883584, 3145728, 3407872, 3670016, 3932160 };
818  static const uint8_t offsetbits[] =
819  { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
820  5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
821  11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
822  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
823  18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 };
824  static const uint8_t shortbases[] =
825  { 0, 4, 8, 16, 32, 64, 128, 192 };
826  static const uint8_t shortbits[] =
827  { 2, 2, 3, 4, 5, 6, 6, 6 };
828 
829  struct ar_archive_rar_uncomp_v3 *uncomp_v3 = &rar->uncomp.state.v3;
830  LZSS *lzss = &rar->uncomp.lzss;
831  int symbol, offs, len, i;
832 
833  if (rar->uncomp.version == 2)
834  return rar_expand_v2(rar, end);
835 
836  for (;;) {
837  if (lzss_position(lzss) >= end)
838  return end;
839 
840  if (uncomp_v3->is_ppmd_block) {
841  if (!rar_handle_ppmd_sequence(rar, &end))
842  return -1;
843  if (rar->uncomp.start_new_table)
844  return lzss_position(lzss);
845  continue;
846  }
847 
848  symbol = rar_read_next_symbol(rar, &uncomp_v3->maincode);
849  if (symbol < 0)
850  return -1;
851  if (symbol < 256) {
852  lzss_emit_literal(lzss, (uint8_t)symbol);
853  continue;
854  }
855  if (symbol == 256) {
856  if (!br_check(rar, 1))
857  return -1;
858  if (!br_bits(rar, 1)) {
859  if (!br_check(rar, 1))
860  return -1;
861  rar->uncomp.start_new_table = br_bits(rar, 1) != 0;
862  return lzss_position(lzss);
863  }
864  if (!rar_parse_codes(rar))
865  return -1;
866  continue;
867  }
868  if (symbol == 257) {
869  if (!rar_read_filter(rar, rar_decode_byte, &end))
870  return -1;
871  continue;
872  }
873  if (symbol == 258) {
874  if (uncomp_v3->lastlength == 0)
875  continue;
876  offs = uncomp_v3->lastoffset;
877  len = uncomp_v3->lastlength;
878  }
879  else if (symbol <= 262) {
880  int idx = symbol - 259;
881  int lensymbol = rar_read_next_symbol(rar, &uncomp_v3->lengthcode);
882  offs = uncomp_v3->oldoffset[idx];
883  if (lensymbol < 0 || lensymbol > (int)(sizeof(lengthbases) / sizeof(lengthbases[0])) || lensymbol > (int)(sizeof(lengthbits) / sizeof(lengthbits[0]))) {
884  warn("Invalid data in bitstream");
885  return -1;
886  }
887  len = lengthbases[lensymbol] + 2;
888  if (lengthbits[lensymbol] > 0) {
889  if (!br_check(rar, lengthbits[lensymbol]))
890  return -1;
891  len += (uint8_t)br_bits(rar, lengthbits[lensymbol]);
892  }
893  for (i = idx; i > 0; i--)
894  uncomp_v3->oldoffset[i] = uncomp_v3->oldoffset[i - 1];
895  uncomp_v3->oldoffset[0] = offs;
896  }
897  else if (symbol <= 270) {
898  int idx = symbol - 263;
899  offs = shortbases[idx] + 1;
900  if (shortbits[idx] > 0) {
901  if (!br_check(rar, shortbits[idx]))
902  return -1;
903  offs += (uint8_t)br_bits(rar, shortbits[idx]);
904  }
905  len = 2;
906  for (i = 3; i > 0; i--)
907  uncomp_v3->oldoffset[i] = uncomp_v3->oldoffset[i - 1];
908  uncomp_v3->oldoffset[0] = offs;
909  }
910  else {
911  int idx = symbol - 271;
912  int offssymbol;
913  if (idx > (int)(sizeof(lengthbases) / sizeof(lengthbases[0])) || idx > (int)(sizeof(lengthbits) / sizeof(lengthbits[0]))) {
914  warn("Invalid data in bitstream");
915  return -1;
916  }
917  len = lengthbases[idx] + 3;
918  if (lengthbits[idx] > 0) {
919  if (!br_check(rar, lengthbits[idx]))
920  return -1;
921  len += (uint8_t)br_bits(rar, lengthbits[idx]);
922  }
923  offssymbol = rar_read_next_symbol(rar, &uncomp_v3->offsetcode);
924  if (offssymbol < 0 || offssymbol > (int)(sizeof(offsetbases) / sizeof(offsetbases[0])) || offssymbol > (int)(sizeof(offsetbits) / sizeof(offsetbits[0]))) {
925  warn("Invalid data in bitstream");
926  return -1;
927  }
928  offs = offsetbases[offssymbol] + 1;
929  if (offsetbits[offssymbol] > 0) {
930  if (offssymbol > 9) {
931  if (offsetbits[offssymbol] > 4) {
932  if (!br_check(rar, offsetbits[offssymbol] - 4))
933  return -1;
934  offs += (int)br_bits(rar, offsetbits[offssymbol] - 4) << 4;
935  }
936  if (uncomp_v3->numlowoffsetrepeats > 0) {
937  uncomp_v3->numlowoffsetrepeats--;
938  offs += uncomp_v3->lastlowoffset;
939  }
940  else {
941  int lowoffsetsymbol = rar_read_next_symbol(rar, &uncomp_v3->lowoffsetcode);
942  if (lowoffsetsymbol < 0)
943  return -1;
944  if (lowoffsetsymbol == 16) {
945  uncomp_v3->numlowoffsetrepeats = 15;
946  offs += uncomp_v3->lastlowoffset;
947  }
948  else {
949  offs += lowoffsetsymbol;
950  uncomp_v3->lastlowoffset = lowoffsetsymbol;
951  }
952  }
953  }
954  else {
955  if (!br_check(rar, offsetbits[offssymbol]))
956  return -1;
957  offs += (int)br_bits(rar, offsetbits[offssymbol]);
958  }
959  }
960 
961  if (offs >= 0x40000)
962  len++;
963  if (offs >= 0x2000)
964  len++;
965 
966  for (i = 3; i > 0; i--)
967  uncomp_v3->oldoffset[i] = uncomp_v3->oldoffset[i - 1];
968  uncomp_v3->oldoffset[0] = offs;
969  }
970 
971  uncomp_v3->lastoffset = offs;
972  uncomp_v3->lastlength = len;
973 
974  lzss_emit_match(lzss, offs, len);
975  }
976 }

+ Here is the caller graph for this function:

void rar_free_code ( struct huffman_code code)

Definition at line 137 of file huffman-rar.c.

138 {
139  free(code->tree);
140  free(code->table);
141  memset(code, 0, sizeof(*code));
142 }

+ Here is the caller graph for this function:

const char* rar_get_name ( ar_archive ar)

Definition at line 187 of file parse-rar.c.

188 {
189  ar_archive_rar *rar = (ar_archive_rar *)ar;
190  if (!rar->entry.name) {
191  unsigned char data[21];
192  uint16_t namelen;
193  char *name;
194 
195  struct rar_header header;
196  if (!ar_seek(ar->stream, ar->entry_offset, SEEK_SET))
197  return NULL;
198  if (!rar_parse_header(ar, &header))
199  return NULL;
200  if (ar_read(ar->stream, data, sizeof(data)) != sizeof(data))
201  return NULL;
202  if ((header.flags & LHD_LARGE) && !ar_skip(ar->stream, 8))
203  return NULL;
204 
205  namelen = uint16le(data + 15);
206  name = malloc(namelen + 1);
207  if (!name || ar_read(ar->stream, name, namelen) != namelen) {
208  free(name);
209  return NULL;
210  }
211  name[namelen] = '\0';
212 
213  if (!(header.flags & LHD_UNICODE)) {
214  rar->entry.name = ar_conv_dos_to_utf8(name);
215  free(name);
216  }
217  else if (namelen == strlen(name)) {
218  rar->entry.name = name;
219  }
220  else {
221  rar->entry.name = rar_conv_unicode_to_utf8(name, namelen);
222  free(name);
223  }
224  /* normalize path separators */
225  if (rar->entry.name) {
226  char *p = rar->entry.name;
227  while ((p = strchr(p, '\\')) != NULL) {
228  *p = '/';
229  }
230  }
231 
232  if (!ar_seek(ar->stream, ar->entry_offset + rar->entry.header_size, SEEK_SET))
233  warn("Couldn't seek back to the end of the entry header");
234  }
235  return rar->entry.name;
236 }

+ Here is the caller graph for this function:

static bool rar_is_leaf_node ( struct huffman_code code,
int  node 
)
inlinestatic

Definition at line 126 of file rar.h.

126 { return code->tree[node].branches[0] == code->tree[node].branches[1]; }

+ Here is the caller graph for this function:

bool rar_make_table ( struct huffman_code code)

Definition at line 121 of file huffman-rar.c.

122 {
123  if (code->minlength <= code->maxlength && code->maxlength <= 10)
124  code->tablesize = code->maxlength;
125  else
126  code->tablesize = 10;
127 
128  code->table = calloc(1ULL << code->tablesize, sizeof(*code->table));
129  if (!code->table) {
130  warn("OOM during decompression");
131  return false;
132  }
133 
134  return rar_make_table_rec(code, 0, 0, 0, code->tablesize);
135 }

+ Here is the caller graph for this function:

bool rar_new_node ( struct huffman_code code)

Definition at line 8 of file huffman-rar.c.

9 {
10  if (!code->tree) {
11  code->minlength = INT_MAX;
12  code->maxlength = INT_MIN;
13  }
14  if (code->numentries + 1 >= code->capacity) {
15  /* in my small file sample, 1024 is the value needed most often */
16  int new_capacity = code->capacity ? code->capacity * 2 : 1024;
17  void *new_tree = calloc(new_capacity, sizeof(*code->tree));
18  if (!new_tree) {
19  warn("OOM during decompression");
20  return false;
21  }
22  memcpy(new_tree, code->tree, code->capacity * sizeof(*code->tree));
23  free(code->tree);
24  code->tree = new_tree;
25  code->capacity = new_capacity;
26  }
27  code->tree[code->numentries].branches[0] = -1;
28  code->tree[code->numentries].branches[1] = -2;
29  code->numentries++;
30  return true;
31 }

+ Here is the caller graph for this function:

bool rar_parse_filter ( ar_archive_rar rar,
const uint8_t *  bytes,
uint16_t  length,
uint8_t  flags 
)

Definition at line 499 of file filter-rar.c.

500 {
501  struct ar_archive_rar_uncomp_v3 *uncomp = &rar->uncomp.state.v3;
502  struct ar_archive_rar_filters *filters = &uncomp->filters;
503 
504  struct MemBitReader br = { 0 };
505  struct RARProgramCode *prog;
506  struct RARFilter *filter, **nextfilter;
507 
508  uint32_t numprogs, num, blocklength, globaldatalen;
509  uint8_t *globaldata;
510  size_t blockstartpos;
511  uint32_t registers[8] = { 0 };
512  uint32_t i;
513 
514  br.bytes = bytes;
515  br.length = length;
516 
517  numprogs = 0;
518  for (prog = filters->progs; prog; prog = prog->next)
519  numprogs++;
520 
521  if ((flags & 0x80)) {
522  num = br_next_rarvm_number(&br);
523  if (num == 0) {
524  rar_delete_filter(filters->stack);
525  filters->stack = NULL;
526  rar_delete_program(filters->progs);
527  filters->progs = NULL;
528  }
529  else
530  num--;
531  if (num > numprogs) {
532  warn("Invalid program number");
533  return false;
534  }
535  filters->lastfilternum = num;
536  }
537  else
538  num = filters->lastfilternum;
539 
540  prog = filters->progs;
541  for (i = 0; i < num; i++)
542  prog = prog->next;
543  if (prog)
544  prog->usagecount++;
545 
546  blockstartpos = br_next_rarvm_number(&br) + (size_t)lzss_position(&rar->uncomp.lzss);
547  if ((flags & 0x40))
548  blockstartpos += 258;
549  if ((flags & 0x20))
550  blocklength = br_next_rarvm_number(&br);
551  else
552  blocklength = prog ? prog->oldfilterlength : 0;
553 
554  registers[3] = RARProgramSystemGlobalAddress;
555  registers[4] = blocklength;
556  registers[5] = prog ? prog->usagecount : 0;
557  registers[7] = RARProgramMemorySize;
558 
559  if ((flags & 0x10)) {
560  uint8_t mask = (uint8_t)br_bits(&br, 7);
561  for (i = 0; i < 7; i++) {
562  if ((mask & (1 << i)))
563  registers[i] = br_next_rarvm_number(&br);
564  }
565  }
566 
567  if (!prog) {
568  uint32_t len = br_next_rarvm_number(&br);
569  uint8_t *bytecode;
570  struct RARProgramCode **next;
571 
572  if (len == 0 || len > 0x10000) {
573  warn("Invalid RARVM bytecode length");
574  return false;
575  }
576  bytecode = malloc(len);
577  if (!bytecode)
578  return false;
579  for (i = 0; i < len; i++)
580  bytecode[i] = (uint8_t)br_bits(&br, 8);
581  prog = rar_compile_program(bytecode, len);
582  if (!prog) {
583  free(bytecode);
584  return false;
585  }
586  free(bytecode);
587  next = &filters->progs;
588  while (*next)
589  next = &(*next)->next;
590  *next = prog;
591  }
592  prog->oldfilterlength = blocklength;
593 
594  globaldata = NULL;
595  globaldatalen = 0;
596  if ((flags & 0x08)) {
597  globaldatalen = br_next_rarvm_number(&br);
598  if (globaldatalen > RARProgramUserGlobalSize) {
599  warn("Invalid RARVM data length");
600  return false;
601  }
602  globaldata = malloc(globaldatalen + RARProgramSystemGlobalSize);
603  if (!globaldata)
604  return false;
605  for (i = 0; i < globaldatalen; i++)
606  globaldata[i + RARProgramSystemGlobalSize] = (uint8_t)br_bits(&br, 8);
607  }
608 
609  if (br.at_eof) {
610  free(globaldata);
611  return false;
612  }
613 
614  filter = rar_create_filter(prog, globaldata, globaldatalen, registers, blockstartpos, blocklength);
615  free(globaldata);
616  if (!filter)
617  return false;
618 
619  for (i = 0; i < 7; i++)
620  bw_write32le(&filter->globaldata[i * 4], registers[i]);
621  bw_write32le(&filter->globaldata[0x1C], blocklength);
622  bw_write32le(&filter->globaldata[0x20], 0);
623  bw_write32le(&filter->globaldata[0x2C], prog->usagecount);
624 
625  nextfilter = &filters->stack;
626  while (*nextfilter)
627  nextfilter = &(*nextfilter)->next;
628  *nextfilter = filter;
629 
630  if (!filters->stack->next)
631  filters->filterstart = blockstartpos;
632 
633  return true;
634 }

+ Here is the caller graph for this function:

bool rar_parse_header ( ar_archive ar,
struct rar_header header 
)

Definition at line 12 of file parse-rar.c.

13 {
14  unsigned char header_data[7];
15  size_t read = ar_read(ar->stream, header_data, sizeof(header_data));
16  if (read == 0) {
17  ar->at_eof = true;
18  return false;
19  }
20  if (read < sizeof(header_data))
21  return false;
22 
23  header->crc = uint16le(header_data + 0);
24  header->type = uint8le(header_data + 2);
25  header->flags = uint16le(header_data + 3);
26  header->size = uint16le(header_data + 5);
27 
28  header->datasize = 0;
29  if ((header->flags & LHD_LONG_BLOCK) || header->type == 0x74) {
30  unsigned char size_data[4];
31  if (!(header->flags & LHD_LONG_BLOCK))
32  log("File header without LHD_LONG_BLOCK set");
33  read += ar_read(ar->stream, size_data, sizeof(size_data));
34  if (read < sizeof(header_data) + sizeof(size_data))
35  return false;
36  header->datasize = uint32le(size_data);
37  }
38 
39  if (header->size < read) {
40  warn("Invalid header size %d", header->size);
41  return false;
42  }
43 
44  return true;
45 }

+ Here is the caller graph for this function:

bool rar_parse_header_entry ( ar_archive_rar rar,
struct rar_header header,
struct rar_entry entry 
)

Definition at line 74 of file parse-rar.c.

75 {
76  unsigned char data[21];
77  if (ar_read(rar->super.stream, data, sizeof(data)) != sizeof(data))
78  return false;
79 
80  entry->size = uint32le(data + 0);
81  entry->os = uint8le(data + 4);
82  entry->crc = uint32le(data + 5);
83  entry->dosdate = uint32le(data + 9);
84  entry->version = uint8le(data + 13);
85  entry->method = uint8le(data + 14);
86  entry->namelen = uint16le(data + 15);
87  entry->attrs = uint32le(data + 17);
88  if ((header->flags & LHD_LARGE)) {
89  unsigned char more_data[8];
90  if (ar_read(rar->super.stream, more_data, sizeof(more_data)) != sizeof(more_data))
91  return false;
92  header->datasize += (uint64_t)uint32le(more_data + 0);
93  entry->size += (uint64_t)uint32le(more_data + 4);
94  }
95  if (!ar_skip(rar->super.stream, entry->namelen))
96  return false;
97  if ((header->flags & LHD_SALT)) {
98  log("Skipping LHD_SALT");
99  ar_skip(rar->super.stream, 8);
100  }
101 
102  rar->entry.version = entry->version;
103  rar->entry.method = entry->method;
104  rar->entry.crc = entry->crc;
105  rar->entry.header_size = header->size;
106  rar->entry.solid = entry->version < 20 ? (rar->archive_flags & MHD_SOLID) : (header->flags & LHD_SOLID);
107  free(rar->entry.name);
108  rar->entry.name = NULL;
109 
110  return true;
111 }

+ Here is the caller graph for this function:

bool rar_run_filters ( ar_archive_rar rar)

Definition at line 636 of file filter-rar.c.

637 {
638  struct ar_archive_rar_filters *filters = &rar->uncomp.state.v3.filters;
639  struct RARFilter *filter = filters->stack;
640  size_t start = filters->filterstart;
641  size_t end = start + filter->blocklength;
642  uint32_t lastfilteraddress;
643  uint32_t lastfilterlength;
644 
645  filters->filterstart = SIZE_MAX;
646  end = (size_t)rar_expand(rar, end);
647  if (end != start + filter->blocklength) {
648  warn("Failed to expand the expected amout of bytes");
649  return false;
650  }
651 
652  if (!filters->vm) {
653  filters->vm = calloc(1, sizeof(*filters->vm));
654  if (!filters->vm)
655  return false;
656  }
657 
658  lzss_copy_bytes_from_window(&rar->uncomp.lzss, filters->vm->memory, start, filter->blocklength);
659  if (!rar_execute_filter(filter, filters->vm, rar->progress.bytes_done)) {
660  warn("Failed to execute parsing filter");
661  return false;
662  }
663 
664  lastfilteraddress = filter->filteredblockaddress;
665  lastfilterlength = filter->filteredblocklength;
666  filters->stack = filter->next;
667  filter->next = NULL;
668  rar_delete_filter(filter);
669 
670  while ((filter = filters->stack) != NULL && filter->blockstartpos == filters->filterstart && filter->blocklength == lastfilterlength) {
671  memmove(&filters->vm->memory[0], &filters->vm->memory[lastfilteraddress], lastfilterlength);
672  if (!rar_execute_filter(filter, filters->vm, rar->progress.bytes_done)) {
673  warn("Failed to execute parsing filter");
674  return false;
675  }
676 
677  lastfilteraddress = filter->filteredblockaddress;
678  lastfilterlength = filter->filteredblocklength;
679  filters->stack = filter->next;
680  filter->next = NULL;
681  rar_delete_filter(filter);
682  }
683 
684  if (filters->stack) {
685  if (filters->stack->blockstartpos < end) {
686  warn("Bad filter order");
687  return false;
688  }
689  filters->filterstart = filters->stack->blockstartpos;
690  }
691 
692  filters->lastend = end;
693  filters->bytes = &filters->vm->memory[lastfilteraddress];
694  filters->bytes_ready = lastfilterlength;
695 
696  return true;
697 }

+ Here is the caller graph for this function:

bool rar_uncompress_part ( ar_archive_rar rar,
void *  buffer,
size_t  buffer_size 
)

Definition at line 978 of file uncompress-rar.c.

979 {
980  struct ar_archive_rar_uncomp *uncomp = &rar->uncomp;
981  struct ar_archive_rar_uncomp_v3 *uncomp_v3 = NULL;
982  size_t end;
983 
984  if (!rar_init_uncompress(uncomp, rar->entry.version))
985  return false;
986  if (uncomp->version == 3)
987  uncomp_v3 = &uncomp->state.v3;
988 
989  for (;;) {
990  if (uncomp_v3 && uncomp_v3->filters.bytes_ready > 0) {
991  size_t count = smin(uncomp_v3->filters.bytes_ready, buffer_size);
992  memcpy(buffer, uncomp_v3->filters.bytes, count);
993  uncomp_v3->filters.bytes_ready -= count;
994  uncomp_v3->filters.bytes += count;
995  rar->progress.bytes_done += count;
996  buffer_size -= count;
997  buffer = (uint8_t *)buffer + count;
999  goto FinishBlock;
1000  }
1001  else if (uncomp->bytes_ready > 0) {
1002  int count = (int)smin(uncomp->bytes_ready, buffer_size);
1003  lzss_copy_bytes_from_window(&uncomp->lzss, buffer, rar->progress.bytes_done + rar->solid.size_total, count);
1004  uncomp->bytes_ready -= count;
1005  rar->progress.bytes_done += count;
1006  buffer_size -= count;
1007  buffer = (uint8_t *)buffer + count;
1008  }
1009  if (buffer_size == 0)
1010  return true;
1011 
1012  if (uncomp->br.at_eof)
1013  return false;
1014 
1015  if (uncomp_v3 && uncomp_v3->filters.lastend == uncomp_v3->filters.filterstart) {
1016  if (!rar_run_filters(rar))
1017  return false;
1018  continue;
1019  }
1020 
1021 FinishBlock:
1022  if (uncomp->start_new_table && !rar_parse_codes(rar))
1023  return false;
1024 
1026  if (uncomp_v3 && uncomp_v3->filters.filterstart < end)
1027  end = uncomp_v3->filters.filterstart;
1028  end = (size_t)rar_expand(rar, end);
1029  if (end == (size_t)-1 || end < rar->progress.bytes_done + rar->solid.size_total)
1030  return false;
1031  uncomp->bytes_ready = end - rar->progress.bytes_done - rar->solid.size_total;
1032  if (uncomp_v3)
1033  uncomp_v3->filters.lastend = end;
1034 
1035  if (uncomp_v3 && uncomp_v3->is_ppmd_block && uncomp->start_new_table)
1036  goto FinishBlock;
1037  }
1038 }

+ Here is the caller graph for this function:

static size_t smin ( size_t  a,
size_t  b 
)
inlinestatic

Definition at line 13 of file rar.h.

13 { return a < b ? a : b; }

+ Here is the caller graph for this function: