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