1 /* Copyright 2015 the unarr project authors (see AUTHORS file).
2 License: LGPLv3 */
3
4 #include "rar.h"
5 #include "rarvm.h"
6
7 /* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/XADRARVirtualMachine.m */
8 /* adapted from https://code.google.com/p/theunarchiver/source/browse/XADMaster/XADRAR30Filter.m */
9
10 struct MemBitReader {
11 const uint8_t *bytes;
12 size_t length;
13 size_t offset;
14 uint64_t bits;
15 int available;
16 bool at_eof;
17 };
18
19 struct RARProgramCode {
20 RARProgram *prog;
21 uint8_t *staticdata;
22 uint32_t staticdatalen;
23 uint8_t *globalbackup;
24 uint32_t globalbackuplen;
25 uint64_t fingerprint;
26 uint32_t usagecount;
27 uint32_t oldfilterlength;
28 struct RARProgramCode *next;
29 };
30
31 struct RARFilter {
32 struct RARProgramCode *prog;
33 uint32_t initialregisters[8];
34 uint8_t *globaldata;
35 uint32_t globaldatalen;
36 size_t blockstartpos;
37 uint32_t blocklength;
38 uint32_t filteredblockaddress;
39 uint32_t filteredblocklength;
40 struct RARFilter *next;
41 };
42
br_fill(struct MemBitReader * br,int bits)43 static bool br_fill(struct MemBitReader *br, int bits)
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 }
55
br_bits(struct MemBitReader * br,int bits)56 static inline uint32_t br_bits(struct MemBitReader *br, int bits)
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 }
62
br_available(struct MemBitReader * br,int bits)63 static inline bool br_available(struct MemBitReader *br, int bits)
64 {
65 return !br->at_eof && (bits <= br->available || br_fill(br, bits));
66 }
67
br_next_rarvm_number(struct MemBitReader * br)68 static uint32_t br_next_rarvm_number(struct MemBitReader *br)
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 }
85
bw_write32le(uint8_t * dst,uint32_t value)86 static void bw_write32le(uint8_t *dst, uint32_t value)
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 }
93
rar_delete_program(struct RARProgramCode * prog)94 static void rar_delete_program(struct RARProgramCode *prog)
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 }
105
rar_parse_operand(struct MemBitReader * br,uint8_t instruction,bool bytemode,uint32_t instrcount,uint8_t * addressmode,uint32_t * value)106 static bool rar_parse_operand(struct MemBitReader *br, uint8_t instruction, bool bytemode, uint32_t instrcount, uint8_t *addressmode, uint32_t *value)
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 }
147
rar_compile_program(const uint8_t * bytes,size_t length)148 static struct RARProgramCode *rar_compile_program(const uint8_t *bytes, size_t length)
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 }
224
rar_execute_filter_prog(struct RARFilter * filter,RARVirtualMachine * vm)225 static bool rar_execute_filter_prog(struct RARFilter *filter, RARVirtualMachine *vm)
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 }
238 RARSetVirtualMachineRegisters(vm, filter->initialregisters);
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;
258 memcpy(filter->globaldata, &vm->memory[RARProgramSystemGlobalAddress], filter->globaldatalen);
259 }
260 else
261 filter->globaldatalen = 0;
262
263 return true;
264 }
265
rar_create_filter(struct RARProgramCode * prog,const uint8_t * globaldata,uint32_t globaldatalen,uint32_t registers[8],size_t startpos,uint32_t length)266 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)
267 {
268 struct RARFilter *filter;
269
270 filter = calloc(1, sizeof(*filter));
271 if (!filter)
272 return NULL;
273 filter->prog = prog;
274 filter->globaldatalen = globaldatalen > RARProgramSystemGlobalSize ? globaldatalen : RARProgramSystemGlobalSize;
275 filter->globaldata = calloc(1, filter->globaldatalen);
276 if (!filter->globaldata)
277 return NULL;
278 if (globaldata)
279 memcpy(filter->globaldata, globaldata, globaldatalen);
280 if (registers)
281 memcpy(filter->initialregisters, registers, sizeof(filter->initialregisters));
282 filter->blockstartpos = startpos;
283 filter->blocklength = length;
284
285 return filter;
286 }
287
rar_delete_filter(struct RARFilter * filter)288 static void rar_delete_filter(struct RARFilter *filter)
289 {
290 while (filter) {
291 struct RARFilter *next = filter->next;
292 free(filter->globaldata);
293 free(filter);
294 filter = next;
295 }
296 }
297
rar_execute_filter_delta(struct RARFilter * filter,RARVirtualMachine * vm)298 static bool rar_execute_filter_delta(struct RARFilter *filter, RARVirtualMachine *vm)
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 }
321
rar_execute_filter_e8(struct RARFilter * filter,RARVirtualMachine * vm,size_t pos,bool e9also)322 static bool rar_execute_filter_e8(struct RARFilter *filter, RARVirtualMachine *vm, size_t pos, bool e9also)
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 }
348
rar_execute_filter_rgb(struct RARFilter * filter,RARVirtualMachine * vm)349 static bool rar_execute_filter_rgb(struct RARFilter *filter, RARVirtualMachine *vm)
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 }
388
rar_execute_filter_audio(struct RARFilter * filter,RARVirtualMachine * vm)389 static bool rar_execute_filter_audio(struct RARFilter *filter, RARVirtualMachine *vm)
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 }
444
rar_execute_filter(struct RARFilter * filter,RARVirtualMachine * vm,size_t pos)445 static bool rar_execute_filter(struct RARFilter *filter, RARVirtualMachine *vm, size_t pos)
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 */
460 if (filter->prog->globalbackuplen > RARProgramSystemGlobalSize) {
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
477 filter->filteredblockaddress = RARVirtualMachineRead32(vm, RARProgramSystemGlobalAddress + 0x20) & RARProgramMemoryMask;
478 filter->filteredblocklength = RARVirtualMachineRead32(vm, RARProgramSystemGlobalAddress + 0x1C) & RARProgramMemoryMask;
479 if (filter->filteredblockaddress + filter->filteredblocklength >= RARProgramMemorySize) {
480 filter->filteredblockaddress = filter->filteredblocklength = 0;
481 return false;
482 }
483
484 if (filter->globaldatalen > RARProgramSystemGlobalSize) {
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 }
498
rar_parse_filter(ar_archive_rar * rar,const uint8_t * bytes,uint16_t length,uint8_t flags)499 bool rar_parse_filter(ar_archive_rar *rar, const uint8_t *bytes, uint16_t length, uint8_t flags)
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 }
635
rar_run_filters(ar_archive_rar * rar)636 bool rar_run_filters(ar_archive_rar *rar)
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 amount 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 }
698
rar_clear_filters(struct ar_archive_rar_filters * filters)699 void rar_clear_filters(struct ar_archive_rar_filters *filters)
700 {
701 rar_delete_filter(filters->stack);
702 rar_delete_program(filters->progs);
703 free(filters->vm);
704 }
705