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
filter-rar.c File Reference
#include "rar.h"
#include "rarvm.h"
+ Include dependency graph for filter-rar.c:

Go to the source code of this file.

Data Structures

struct  MemBitReader
 
struct  RARProgramCode
 
struct  RARFilter
 

Functions

static bool br_fill (struct MemBitReader *br, int bits)
 
static uint32_t br_bits (struct MemBitReader *br, int bits)
 
static bool br_available (struct MemBitReader *br, int bits)
 
static uint32_t br_next_rarvm_number (struct MemBitReader *br)
 
static void bw_write32le (uint8_t *dst, uint32_t value)
 
static void rar_delete_program (struct RARProgramCode *prog)
 
static bool rar_parse_operand (struct MemBitReader *br, uint8_t instruction, bool bytemode, uint32_t instrcount, uint8_t *addressmode, uint32_t *value)
 
static struct RARProgramCoderar_compile_program (const uint8_t *bytes, size_t length)
 
static bool rar_execute_filter_prog (struct RARFilter *filter, RARVirtualMachine *vm)
 
static struct RARFilterrar_create_filter (struct RARProgramCode *prog, const uint8_t *globaldata, uint32_t globaldatalen, uint32_t registers[8], size_t startpos, uint32_t length)
 
static void rar_delete_filter (struct RARFilter *filter)
 
static bool rar_execute_filter_delta (struct RARFilter *filter, RARVirtualMachine *vm)
 
static bool rar_execute_filter_e8 (struct RARFilter *filter, RARVirtualMachine *vm, size_t pos, bool e9also)
 
static bool rar_execute_filter_rgb (struct RARFilter *filter, RARVirtualMachine *vm)
 
static bool rar_execute_filter_audio (struct RARFilter *filter, RARVirtualMachine *vm)
 
static bool rar_execute_filter (struct RARFilter *filter, RARVirtualMachine *vm, size_t pos)
 
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)
 

Function Documentation

static bool br_available ( struct MemBitReader br,
int  bits 
)
inlinestatic

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

64 {
65  return !br->at_eof && (bits <= br->available || br_fill(br, bits));
66 }

+ Here is the caller graph for this function:

static uint32_t br_bits ( struct MemBitReader br,
int  bits 
)
inlinestatic

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

57 {
58  if (bits > br->available && (br->at_eof || !br_fill(br, bits)))
59  return 0;
60  return (uint32_t)((br->bits >> (br->available -= bits)) & (((uint64_t)1 << bits) - 1));
61 }

+ Here is the caller graph for this function:

static bool br_fill ( struct MemBitReader br,
int  bits 
)
static

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

44 {
45  while (br->available < bits && br->offset < br->length) {
46  br->bits = (br->bits << 8) | br->bytes[br->offset++];
47  br->available += 8;
48  }
49  if (bits > br->available) {
50  br->at_eof = true;
51  return false;
52  }
53  return true;
54 }

+ Here is the caller graph for this function:

static uint32_t br_next_rarvm_number ( struct MemBitReader br)
static

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

69 {
70  uint32_t val;
71  switch (br_bits(br, 2)) {
72  case 0:
73  return br_bits(br, 4);
74  case 1:
75  val = br_bits(br, 8);
76  if (val >= 16)
77  return val;
78  return 0xFFFFFF00 | (val << 4) | br_bits(br, 4);
79  case 2:
80  return br_bits(br, 16);
81  default:
82  return br_bits(br, 32);
83  }
84 }

+ Here is the caller graph for this function:

static void bw_write32le ( uint8_t *  dst,
uint32_t  value 
)
static

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

87 {
88  dst[0] = value & 0xFF;
89  dst[1] = (value >> 8) & 0xFF;
90  dst[2] = (value >> 16) & 0xFF;
91  dst[3] = (value >> 24) & 0xFF;
92 }

+ 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:

static struct RARProgramCode* rar_compile_program ( const uint8_t *  bytes,
size_t  length 
)
static

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

149 {
150  struct MemBitReader br = { 0 };
151  struct RARProgramCode *prog;
152  uint32_t instrcount = 0;
153  uint8_t xor;
154  size_t i;
155 
156  xor = 0;
157  for (i = 1; i < length; i++)
158  xor ^= bytes[i];
159  if (!length || xor != bytes[0])
160  return NULL;
161 
162  br.bytes = bytes;
163  br.length = length;
164  br.offset = 1;
165 
166  prog = calloc(1, sizeof(*prog));
167  if (!prog)
168  return NULL;
169  prog->prog = RARCreateProgram();
170  if (!prog->prog) {
171  rar_delete_program(prog);
172  return NULL;
173  }
174  prog->fingerprint = ar_crc32(0, bytes, length) | ((uint64_t)length << 32);
175 
176  if (br_bits(&br, 1)) {
177  prog->staticdatalen = br_next_rarvm_number(&br) + 1;
178  prog->staticdata = malloc(prog->staticdatalen);
179  if (!prog->staticdata) {
180  rar_delete_program(prog);
181  return NULL;
182  }
183  for (i = 0; i < prog->staticdatalen; i++)
184  prog->staticdata[i] = (uint8_t)br_bits(&br, 8);
185  }
186 
187  while (br_available(&br, 8)) {
188  bool ok = true;
189  uint8_t instruction = (uint8_t)br_bits(&br, 4);
190  bool bytemode = false;
191  int numargs = 0;
192  uint8_t addrmode1 = 0, addrmode2 = 0;
193  uint32_t value1 = 0, value2 = 0;
194 
195  if ((instruction & 0x08))
196  instruction = ((instruction << 2) | (uint8_t)br_bits(&br, 2)) - 24;
197  if (RARInstructionHasByteMode(instruction))
198  bytemode = br_bits(&br, 1) != 0;
199  ok = RARProgramAddInstr(prog->prog, instruction, bytemode);
200  numargs = NumberOfRARInstructionOperands(instruction);
201  if (ok && numargs >= 1)
202  ok = rar_parse_operand(&br, instruction, bytemode, instrcount, &addrmode1, &value1);
203  if (ok && numargs == 2)
204  ok = rar_parse_operand(&br, instruction, bytemode, (uint32_t)-1, &addrmode2, &value2);
205  if (ok)
206  ok = RARSetLastInstrOperands(prog->prog, addrmode1, value1, addrmode2, value2);
207  if (!ok) {
208  warn("Invalid RAR program instruction");
209  rar_delete_program(prog);
210  return NULL;
211  }
212  instrcount++;
213  }
214 
215  if (!RARIsProgramTerminated(prog->prog)) {
216  if (!RARProgramAddInstr(prog->prog, RARRetInstruction, false)) {
217  rar_delete_program(prog);
218  return NULL;
219  }
220  }
221 
222  return prog;
223 }

+ Here is the caller graph for this function:

static struct RARFilter* rar_create_filter ( struct RARProgramCode prog,
const uint8_t *  globaldata,
uint32_t  globaldatalen,
uint32_t  registers[8],
size_t  startpos,
uint32_t  length 
)
static

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

267 {
268  struct RARFilter *filter;
269 
270  filter = calloc(1, sizeof(*filter));
271  if (!filter)
272  return NULL;
273  filter->prog = prog;
275  filter->globaldata = calloc(1, filter->globaldatalen);
276  if (!filter->globaldata)
277  return NULL;
278  if (globaldata)
280  if (registers)
281  memcpy(filter->initialregisters, registers, sizeof(filter->initialregisters));
282  filter->blockstartpos = startpos;
283  filter->blocklength = length;
284 
285  return filter;
286 }

+ Here is the caller graph for this function:

static void rar_delete_filter ( struct RARFilter filter)
static

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

289 {
290  while (filter) {
291  struct RARFilter *next = filter->next;
292  free(filter->globaldata);
293  free(filter);
294  filter = next;
295  }
296 }

+ Here is the caller graph for this function:

static void rar_delete_program ( struct RARProgramCode prog)
static

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

95 {
96  while (prog) {
97  struct RARProgramCode *next = prog->next;
98  RARDeleteProgram(prog->prog);
99  free(prog->staticdata);
100  free(prog->globalbackup);
101  free(prog);
102  prog = next;
103  }
104 }

+ Here is the caller graph for this function:

static bool rar_execute_filter ( struct RARFilter filter,
RARVirtualMachine vm,
size_t  pos 
)
static

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

446 {
447  if (filter->prog->fingerprint == 0x1D0E06077D)
448  return rar_execute_filter_delta(filter, vm);
449  if (filter->prog->fingerprint == 0x35AD576887)
450  return rar_execute_filter_e8(filter, vm, pos, false);
451  if (filter->prog->fingerprint == 0x393CD7E57E)
452  return rar_execute_filter_e8(filter, vm, pos, true);
453  if (filter->prog->fingerprint == 0x951C2C5DC8)
454  return rar_execute_filter_rgb(filter, vm);
455  if (filter->prog->fingerprint == 0xD8BC85E701)
456  return rar_execute_filter_audio(filter, vm);
457  log("Unknown parsing filter 0x%x%08x", (uint32_t)(filter->prog->fingerprint >> 32), (uint32_t)filter->prog->fingerprint);
458 
459  /* XADRAR30Filter.m @executeOnVirtualMachine claims that this is required */
461  uint8_t *newglobaldata = malloc(filter->prog->globalbackuplen);
462  if (newglobaldata) {
463  free(filter->globaldata);
464  filter->globaldata = newglobaldata;
465  filter->globaldatalen = filter->prog->globalbackuplen;
466  memcpy(filter->globaldata, filter->prog->globalbackup, filter->prog->globalbackuplen);
467  }
468  }
469 
470  filter->initialregisters[6] = (uint32_t)pos;
471  bw_write32le(&filter->globaldata[0x24], (uint32_t)pos);
472  bw_write32le(&filter->globaldata[0x28], (uint32_t)((uint64_t)pos >> 32));
473 
474  if (!rar_execute_filter_prog(filter, vm))
475  return false;
476 
480  filter->filteredblockaddress = filter->filteredblocklength = 0;
481  return false;
482  }
483 
485  uint8_t *newglobalbackup = malloc(filter->globaldatalen);
486  if (newglobalbackup) {
487  free(filter->prog->globalbackup);
488  filter->prog->globalbackup = newglobalbackup;
489  filter->prog->globalbackuplen = filter->globaldatalen;
490  memcpy(filter->prog->globalbackup, filter->globaldata, filter->globaldatalen);
491  }
492  }
493  else
494  filter->prog->globalbackuplen = 0;
495 
496  return true;
497 }

+ Here is the caller graph for this function:

static bool rar_execute_filter_audio ( struct RARFilter filter,
RARVirtualMachine vm 
)
static

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

390 {
391  uint32_t length = filter->initialregisters[4];
392  uint32_t numchannels = filter->initialregisters[0];
393  uint8_t *src, *dst;
394  uint32_t i, j;
395 
396  if (length > RARProgramWorkSize / 2)
397  return false;
398 
399  src = &vm->memory[0];
400  dst = &vm->memory[length];
401  for (i = 0; i < numchannels; i++) {
402  struct AudioState state;
403  memset(&state, 0, sizeof(state));
404  for (j = i; j < length; j += numchannels) {
405  int8_t delta = (int8_t)*src++;
406  uint8_t predbyte, byte;
407  int prederror;
408  state.delta[2] = state.delta[1];
409  state.delta[1] = state.lastdelta - state.delta[0];
410  state.delta[0] = state.lastdelta;
411  predbyte = ((8 * state.lastbyte + state.weight[0] * state.delta[0] + state.weight[1] * state.delta[1] + state.weight[2] * state.delta[2]) >> 3) & 0xFF;
412  byte = (predbyte - delta) & 0xFF;
413  prederror = delta << 3;
414  state.error[0] += abs(prederror);
415  state.error[1] += abs(prederror - state.delta[0]); state.error[2] += abs(prederror + state.delta[0]);
416  state.error[3] += abs(prederror - state.delta[1]); state.error[4] += abs(prederror + state.delta[1]);
417  state.error[5] += abs(prederror - state.delta[2]); state.error[6] += abs(prederror + state.delta[2]);
418  state.lastdelta = (int8_t)(byte - state.lastbyte);
419  dst[j] = state.lastbyte = byte;
420  if (!(state.count++ & 0x1F)) {
421  uint8_t k, idx = 0;
422  for (k = 1; k < 7; k++) {
423  if (state.error[k] < state.error[idx])
424  idx = k;
425  }
426  memset(state.error, 0, sizeof(state.error));
427  switch (idx) {
428  case 1: if (state.weight[0] >= -16) state.weight[0]--; break;
429  case 2: if (state.weight[0] < 16) state.weight[0]++; break;
430  case 3: if (state.weight[1] >= -16) state.weight[1]--; break;
431  case 4: if (state.weight[1] < 16) state.weight[1]++; break;
432  case 5: if (state.weight[2] >= -16) state.weight[2]--; break;
433  case 6: if (state.weight[2] < 16) state.weight[2]++; break;
434  }
435  }
436  }
437  }
438 
439  filter->filteredblockaddress = length;
440  filter->filteredblocklength = length;
441 
442  return true;
443 }

+ Here is the caller graph for this function:

static bool rar_execute_filter_delta ( struct RARFilter filter,
RARVirtualMachine vm 
)
static

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

299 {
300  uint32_t length = filter->initialregisters[4];
301  uint32_t numchannels = filter->initialregisters[0];
302  uint8_t *src, *dst;
303  uint32_t i, idx;
304 
305  if (length > RARProgramWorkSize / 2)
306  return false;
307 
308  src = &vm->memory[0];
309  dst = &vm->memory[length];
310  for (i = 0; i < numchannels; i++) {
311  uint8_t lastbyte = 0;
312  for (idx = i; idx < length; idx += numchannels)
313  lastbyte = dst[idx] = lastbyte - *src++;
314  }
315 
316  filter->filteredblockaddress = length;
317  filter->filteredblocklength = length;
318 
319  return true;
320 }

+ Here is the caller graph for this function:

static bool rar_execute_filter_e8 ( struct RARFilter filter,
RARVirtualMachine vm,
size_t  pos,
bool  e9also 
)
static

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

323 {
324  uint32_t length = filter->initialregisters[4];
325  uint32_t filesize = 0x1000000;
326  uint32_t i;
327 
328  if (length > RARProgramWorkSize || length < 4)
329  return false;
330 
331  for (i = 0; i <= length - 5; i++) {
332  if (vm->memory[i] == 0xE8 || (e9also && vm->memory[i] == 0xE9)) {
333  uint32_t currpos = (uint32_t)pos + i + 1;
334  int32_t address = (int32_t)RARVirtualMachineRead32(vm, i + 1);
335  if (address < 0 && currpos >= (uint32_t)-address)
336  RARVirtualMachineWrite32(vm, i + 1, address + filesize);
337  else if (address >= 0 && (uint32_t)address < filesize)
338  RARVirtualMachineWrite32(vm, i + 1, address - currpos);
339  i += 4;
340  }
341  }
342 
343  filter->filteredblockaddress = 0;
344  filter->filteredblocklength = length;
345 
346  return true;
347 }

+ Here is the caller graph for this function:

static bool rar_execute_filter_prog ( struct RARFilter filter,
RARVirtualMachine vm 
)
static

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

226 {
227  uint32_t newgloballength;
228  uint32_t globallength = filter->globaldatalen;
229  if (globallength > RARProgramSystemGlobalSize)
230  globallength = RARProgramSystemGlobalSize;
231  memcpy(&vm->memory[RARProgramSystemGlobalAddress], filter->globaldata, globallength);
232  if (filter->prog->staticdata) {
233  uint32_t staticlength = filter->prog->staticdatalen;
234  if (staticlength > RARProgramUserGlobalSize - globallength)
235  staticlength = RARProgramUserGlobalSize - globallength;
236  memcpy(&vm->memory[RARProgramUserGlobalAddress], filter->prog->staticdata, staticlength);
237  }
239 
240  if (!RARExecuteProgram(vm, filter->prog->prog)) {
241  warn("Error while executing program in RAR VM");
242  return false;
243  }
244 
245  newgloballength = RARVirtualMachineRead32(vm, RARProgramSystemGlobalAddress + 0x30);
246  if (newgloballength > RARProgramUserGlobalSize)
247  newgloballength = RARProgramUserGlobalSize;
248  if (newgloballength > 0) {
249  uint32_t newglobaldatalength = RARProgramSystemGlobalSize + newgloballength;
250  if (newglobaldatalength > filter->globaldatalen) {
251  uint8_t *newglobaldata = malloc(newglobaldatalength);
252  if (!newglobaldata)
253  return false;
254  free(filter->globaldata);
255  filter->globaldata = newglobaldata;
256  }
257  filter->globaldatalen = newglobaldatalength;
259  }
260  else
261  filter->globaldatalen = 0;
262 
263  return true;
264 }

+ Here is the caller graph for this function:

static bool rar_execute_filter_rgb ( struct RARFilter filter,
RARVirtualMachine vm 
)
static

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

350 {
351  uint32_t stride = filter->initialregisters[0];
352  uint32_t byteoffset = filter->initialregisters[1];
353  uint32_t blocklength = filter->initialregisters[4];
354  uint8_t *src, *dst;
355  uint32_t i, j;
356 
357  if (blocklength > RARProgramWorkSize / 2 || stride > blocklength)
358  return false;
359 
360  src = &vm->memory[0];
361  dst = &vm->memory[blocklength];
362  for (i = 0; i < 3; i++) {
363  uint8_t byte = 0;
364  uint8_t *prev = dst + i - stride;
365  for (j = i; j < blocklength; j += 3) {
366  if (prev >= dst) {
367  uint32_t delta1 = abs(prev[3] - prev[0]);
368  uint32_t delta2 = abs(byte - prev[0]);
369  uint32_t delta3 = abs(prev[3] - prev[0] + byte - prev[0]);
370  if (delta1 > delta2 || delta1 > delta3)
371  byte = delta2 <= delta3 ? prev[3] : prev[0];
372  }
373  byte -= *src++;
374  dst[j] = byte;
375  prev += 3;
376  }
377  }
378  for (i = byteoffset; i < blocklength - 2; i += 3) {
379  dst[i] += dst[i + 1];
380  dst[i + 2] += dst[i + 1];
381  }
382 
383  filter->filteredblockaddress = blocklength;
384  filter->filteredblocklength = blocklength;
385 
386  return true;
387 }

+ 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:

static bool rar_parse_operand ( struct MemBitReader br,
uint8_t  instruction,
bool  bytemode,
uint32_t  instrcount,
uint8_t *  addressmode,
uint32_t *  value 
)
static

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

107 {
108  if (br_bits(br, 1)) {
109  *addressmode = RARRegisterAddressingMode((uint8_t)br_bits(br, 3));
110  *value = 0;
111  }
112  else if (br_bits(br, 1)) {
113  if (br_bits(br, 1)) {
114  if (br_bits(br, 1))
115  *addressmode = RARAbsoluteAddressingMode;
116  else
117  *addressmode = RARIndexedAbsoluteAddressingMode((uint8_t)br_bits(br, 3));
118  *value = br_next_rarvm_number(br);
119  }
120  else {
121  *addressmode = RARRegisterIndirectAddressingMode((uint8_t)br_bits(br, 3));
122  *value = 0;
123  }
124  }
125  else {
126  *addressmode = RARImmediateAddressingMode;
127  if (!bytemode)
128  *value = br_next_rarvm_number(br);
129  else
130  *value = br_bits(br, 8);
131  if (instrcount != (uint32_t)-1 && RARInstructionIsRelativeJump(instruction)) {
132  if (*value >= 256) /* absolute address */
133  *value -= 256;
134  else { /* relative address */
135  if (*value >= 136)
136  *value -= 264;
137  else if (*value >= 16)
138  *value -= 8;
139  else if (*value >= 8)
140  *value -= 16;
141  *value += instrcount;
142  }
143  }
144  }
145  return !br->at_eof;
146 }

+ 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: