1
2
3
4
5
6
7
8
9
10
11#include "xz_private.h"
12#include "xz_lzma2.h"
13
14
15
16
17#define RC_INIT_BYTES 5
18
19
20
21
22
23
24
25
26#define LZMA_IN_REQUIRED 21
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44struct dictionary {
45
46 uint8_t *buf;
47
48
49 size_t start;
50
51
52 size_t pos;
53
54
55
56
57
58 size_t full;
59
60
61 size_t limit;
62
63
64
65
66
67
68 size_t end;
69
70
71
72
73
74
75 uint32_t size;
76
77
78
79
80
81 uint32_t size_max;
82
83
84
85
86
87
88 uint32_t allocated;
89
90
91 enum xz_mode mode;
92};
93
94
95struct rc_dec {
96 uint32_t range;
97 uint32_t code;
98
99
100
101
102
103 uint32_t init_bytes_left;
104
105
106
107
108
109 const uint8_t *in;
110 size_t in_pos;
111 size_t in_limit;
112};
113
114
115struct lzma_len_dec {
116
117 uint16_t choice;
118
119
120 uint16_t choice2;
121
122
123 uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
124
125
126 uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
127
128
129 uint16_t high[LEN_HIGH_SYMBOLS];
130};
131
132struct lzma_dec {
133
134 uint32_t rep0;
135 uint32_t rep1;
136 uint32_t rep2;
137 uint32_t rep3;
138
139
140 enum lzma_state state;
141
142
143
144
145
146 uint32_t len;
147
148
149
150
151
152
153
154 uint32_t lc;
155 uint32_t literal_pos_mask;
156 uint32_t pos_mask;
157
158
159 uint16_t is_match[STATES][POS_STATES_MAX];
160
161
162 uint16_t is_rep[STATES];
163
164
165
166
167
168 uint16_t is_rep0[STATES];
169
170
171
172
173
174 uint16_t is_rep1[STATES];
175
176
177 uint16_t is_rep2[STATES];
178
179
180
181
182
183 uint16_t is_rep0_long[STATES][POS_STATES_MAX];
184
185
186
187
188
189
190 uint16_t dist_slot[DIST_STATES][DIST_SLOTS];
191
192
193
194
195
196 uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END];
197
198
199
200
201
202 uint16_t dist_align[ALIGN_SIZE];
203
204
205 struct lzma_len_dec match_len_dec;
206
207
208 struct lzma_len_dec rep_len_dec;
209
210
211 uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
212};
213
214struct lzma2_dec {
215
216 enum lzma2_seq {
217 SEQ_CONTROL,
218 SEQ_UNCOMPRESSED_1,
219 SEQ_UNCOMPRESSED_2,
220 SEQ_COMPRESSED_0,
221 SEQ_COMPRESSED_1,
222 SEQ_PROPERTIES,
223 SEQ_LZMA_PREPARE,
224 SEQ_LZMA_RUN,
225 SEQ_COPY
226 } sequence;
227
228
229 enum lzma2_seq next_sequence;
230
231
232 uint32_t uncompressed;
233
234
235
236
237
238 uint32_t compressed;
239
240
241
242
243
244 bool need_dict_reset;
245
246
247
248
249
250 bool need_props;
251};
252
253struct xz_dec_lzma2 {
254
255
256
257
258
259
260
261
262
263 struct rc_dec rc;
264 struct dictionary dict;
265 struct lzma2_dec lzma2;
266 struct lzma_dec lzma;
267
268
269
270
271
272 struct {
273 uint32_t size;
274 uint8_t buf[3 * LZMA_IN_REQUIRED];
275 } temp;
276};
277
278
279
280
281
282
283
284
285
286static void XZ_FUNC dict_reset(struct dictionary *dict, struct xz_buf *b)
287{
288 if (DEC_IS_SINGLE(dict->mode)) {
289 dict->buf = b->out + b->out_pos;
290 dict->end = b->out_size - b->out_pos;
291 }
292
293 dict->start = 0;
294 dict->pos = 0;
295 dict->limit = 0;
296 dict->full = 0;
297}
298
299
300static void XZ_FUNC dict_limit(struct dictionary *dict, size_t out_max)
301{
302 if (dict->end - dict->pos <= out_max)
303 dict->limit = dict->end;
304 else
305 dict->limit = dict->pos + out_max;
306}
307
308
309static __always_inline bool XZ_FUNC dict_has_space(const struct dictionary *dict)
310{
311 return dict->pos < dict->limit;
312}
313
314
315
316
317
318
319
320static __always_inline uint32_t XZ_FUNC dict_get(
321 const struct dictionary *dict, uint32_t dist)
322{
323 size_t offset = dict->pos - dist - 1;
324
325 if (dist >= dict->pos)
326 offset += dict->end;
327
328 return dict->full > 0 ? dict->buf[offset] : 0;
329}
330
331
332
333
334static inline void XZ_FUNC dict_put(struct dictionary *dict, uint8_t byte)
335{
336 dict->buf[dict->pos++] = byte;
337
338 if (dict->full < dict->pos)
339 dict->full = dict->pos;
340}
341
342
343
344
345
346
347static bool XZ_FUNC dict_repeat(
348 struct dictionary *dict, uint32_t *len, uint32_t dist)
349{
350 size_t back;
351 uint32_t left;
352
353 if (dist >= dict->full || dist >= dict->size)
354 return false;
355
356 left = min_t(size_t, dict->limit - dict->pos, *len);
357 *len -= left;
358
359 back = dict->pos - dist - 1;
360 if (dist >= dict->pos)
361 back += dict->end;
362
363 do {
364 dict->buf[dict->pos++] = dict->buf[back++];
365 if (back == dict->end)
366 back = 0;
367 } while (--left > 0);
368
369 if (dict->full < dict->pos)
370 dict->full = dict->pos;
371
372 return true;
373}
374
375
376static void XZ_FUNC dict_uncompressed(
377 struct dictionary *dict, struct xz_buf *b, uint32_t *left)
378{
379 size_t copy_size;
380
381 while (*left > 0 && b->in_pos < b->in_size
382 && b->out_pos < b->out_size) {
383 copy_size = min(b->in_size - b->in_pos,
384 b->out_size - b->out_pos);
385 if (copy_size > dict->end - dict->pos)
386 copy_size = dict->end - dict->pos;
387 if (copy_size > *left)
388 copy_size = *left;
389
390 *left -= copy_size;
391
392 memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
393 dict->pos += copy_size;
394
395 if (dict->full < dict->pos)
396 dict->full = dict->pos;
397
398 if (DEC_IS_MULTI(dict->mode)) {
399 if (dict->pos == dict->end)
400 dict->pos = 0;
401
402 memcpy(b->out + b->out_pos, b->in + b->in_pos,
403 copy_size);
404 }
405
406 dict->start = dict->pos;
407
408 b->out_pos += copy_size;
409 b->in_pos += copy_size;
410
411 }
412}
413
414
415
416
417
418
419static uint32_t XZ_FUNC dict_flush(struct dictionary *dict, struct xz_buf *b)
420{
421 size_t copy_size = dict->pos - dict->start;
422
423 if (DEC_IS_MULTI(dict->mode)) {
424 if (dict->pos == dict->end)
425 dict->pos = 0;
426
427 memcpy(b->out + b->out_pos, dict->buf + dict->start,
428 copy_size);
429 }
430
431 dict->start = dict->pos;
432 b->out_pos += copy_size;
433 return copy_size;
434}
435
436
437
438
439
440
441static void XZ_FUNC rc_reset(struct rc_dec *rc)
442{
443 rc->range = (uint32_t)-1;
444 rc->code = 0;
445 rc->init_bytes_left = RC_INIT_BYTES;
446}
447
448
449
450
451
452static bool XZ_FUNC rc_read_init(struct rc_dec *rc, struct xz_buf *b)
453{
454 while (rc->init_bytes_left > 0) {
455 if (b->in_pos == b->in_size)
456 return false;
457
458 rc->code = (rc->code << 8) + b->in[b->in_pos++];
459 --rc->init_bytes_left;
460 }
461
462 return true;
463}
464
465
466static inline bool XZ_FUNC rc_limit_exceeded(const struct rc_dec *rc)
467{
468 return rc->in_pos > rc->in_limit;
469}
470
471
472
473
474
475static inline bool XZ_FUNC rc_is_finished(const struct rc_dec *rc)
476{
477 return rc->code == 0;
478}
479
480
481static __always_inline void XZ_FUNC rc_normalize(struct rc_dec *rc)
482{
483 if (rc->range < RC_TOP_VALUE) {
484 rc->range <<= RC_SHIFT_BITS;
485 rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++];
486 }
487}
488
489
490
491
492
493
494
495
496
497
498
499
500static __always_inline int XZ_FUNC rc_bit(struct rc_dec *rc, uint16_t *prob)
501{
502 uint32_t bound;
503 int bit;
504
505 rc_normalize(rc);
506 bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob;
507 if (rc->code < bound) {
508 rc->range = bound;
509 *prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS;
510 bit = 0;
511 } else {
512 rc->range -= bound;
513 rc->code -= bound;
514 *prob -= *prob >> RC_MOVE_BITS;
515 bit = 1;
516 }
517
518 return bit;
519}
520
521
522static __always_inline uint32_t XZ_FUNC rc_bittree(
523 struct rc_dec *rc, uint16_t *probs, uint32_t limit)
524{
525 uint32_t symbol = 1;
526
527 do {
528 if (rc_bit(rc, &probs[symbol]))
529 symbol = (symbol << 1) + 1;
530 else
531 symbol <<= 1;
532 } while (symbol < limit);
533
534 return symbol;
535}
536
537
538static __always_inline void XZ_FUNC rc_bittree_reverse(struct rc_dec *rc,
539 uint16_t *probs, uint32_t *dest, uint32_t limit)
540{
541 uint32_t symbol = 1;
542 uint32_t i = 0;
543
544 do {
545 if (rc_bit(rc, &probs[symbol])) {
546 symbol = (symbol << 1) + 1;
547 *dest += 1 << i;
548 } else {
549 symbol <<= 1;
550 }
551 } while (++i < limit);
552}
553
554
555static inline void XZ_FUNC rc_direct(
556 struct rc_dec *rc, uint32_t *dest, uint32_t limit)
557{
558 uint32_t mask;
559
560 do {
561 rc_normalize(rc);
562 rc->range >>= 1;
563 rc->code -= rc->range;
564 mask = (uint32_t)0 - (rc->code >> 31);
565 rc->code += rc->range & mask;
566 *dest = (*dest << 1) + (mask + 1);
567 } while (--limit > 0);
568}
569
570
571
572
573
574
575static uint16_t * XZ_FUNC lzma_literal_probs(struct xz_dec_lzma2 *s)
576{
577 uint32_t prev_byte = dict_get(&s->dict, 0);
578 uint32_t low = prev_byte >> (8 - s->lzma.lc);
579 uint32_t high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc;
580 return s->lzma.literal[low + high];
581}
582
583
584static void XZ_FUNC lzma_literal(struct xz_dec_lzma2 *s)
585{
586 uint16_t *probs;
587 uint32_t symbol;
588 uint32_t match_byte;
589 uint32_t match_bit;
590 uint32_t offset;
591 uint32_t i;
592
593 probs = lzma_literal_probs(s);
594
595 if (lzma_state_is_literal(s->lzma.state)) {
596 symbol = rc_bittree(&s->rc, probs, 0x100);
597 } else {
598 symbol = 1;
599 match_byte = dict_get(&s->dict, s->lzma.rep0) << 1;
600 offset = 0x100;
601
602 do {
603 match_bit = match_byte & offset;
604 match_byte <<= 1;
605 i = offset + match_bit + symbol;
606
607 if (rc_bit(&s->rc, &probs[i])) {
608 symbol = (symbol << 1) + 1;
609 offset &= match_bit;
610 } else {
611 symbol <<= 1;
612 offset &= ~match_bit;
613 }
614 } while (symbol < 0x100);
615 }
616
617 dict_put(&s->dict, (uint8_t)symbol);
618 lzma_state_literal(&s->lzma.state);
619}
620
621
622static void XZ_FUNC lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l,
623 uint32_t pos_state)
624{
625 uint16_t *probs;
626 uint32_t limit;
627
628 if (!rc_bit(&s->rc, &l->choice)) {
629 probs = l->low[pos_state];
630 limit = LEN_LOW_SYMBOLS;
631 s->lzma.len = MATCH_LEN_MIN;
632 } else {
633 if (!rc_bit(&s->rc, &l->choice2)) {
634 probs = l->mid[pos_state];
635 limit = LEN_MID_SYMBOLS;
636 s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS;
637 } else {
638 probs = l->high;
639 limit = LEN_HIGH_SYMBOLS;
640 s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS
641 + LEN_MID_SYMBOLS;
642 }
643 }
644
645 s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit;
646}
647
648
649static void XZ_FUNC lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
650{
651 uint16_t *probs;
652 uint32_t dist_slot;
653 uint32_t limit;
654
655 lzma_state_match(&s->lzma.state);
656
657 s->lzma.rep3 = s->lzma.rep2;
658 s->lzma.rep2 = s->lzma.rep1;
659 s->lzma.rep1 = s->lzma.rep0;
660
661 lzma_len(s, &s->lzma.match_len_dec, pos_state);
662
663 probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)];
664 dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS;
665
666 if (dist_slot < DIST_MODEL_START) {
667 s->lzma.rep0 = dist_slot;
668 } else {
669 limit = (dist_slot >> 1) - 1;
670 s->lzma.rep0 = 2 + (dist_slot & 1);
671
672 if (dist_slot < DIST_MODEL_END) {
673 s->lzma.rep0 <<= limit;
674 probs = s->lzma.dist_special + s->lzma.rep0
675 - dist_slot - 1;
676 rc_bittree_reverse(&s->rc, probs,
677 &s->lzma.rep0, limit);
678 } else {
679 rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS);
680 s->lzma.rep0 <<= ALIGN_BITS;
681 rc_bittree_reverse(&s->rc, s->lzma.dist_align,
682 &s->lzma.rep0, ALIGN_BITS);
683 }
684 }
685}
686
687
688
689
690
691static void XZ_FUNC lzma_rep_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
692{
693 uint32_t tmp;
694
695 if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state])) {
696 if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[
697 s->lzma.state][pos_state])) {
698 lzma_state_short_rep(&s->lzma.state);
699 s->lzma.len = 1;
700 return;
701 }
702 } else {
703 if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state])) {
704 tmp = s->lzma.rep1;
705 } else {
706 if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state])) {
707 tmp = s->lzma.rep2;
708 } else {
709 tmp = s->lzma.rep3;
710 s->lzma.rep3 = s->lzma.rep2;
711 }
712
713 s->lzma.rep2 = s->lzma.rep1;
714 }
715
716 s->lzma.rep1 = s->lzma.rep0;
717 s->lzma.rep0 = tmp;
718 }
719
720 lzma_state_long_rep(&s->lzma.state);
721 lzma_len(s, &s->lzma.rep_len_dec, pos_state);
722}
723
724
725static bool XZ_FUNC lzma_main(struct xz_dec_lzma2 *s)
726{
727 uint32_t pos_state;
728
729
730
731
732
733 if (dict_has_space(&s->dict) && s->lzma.len > 0)
734 dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0);
735
736
737
738
739
740 while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc)) {
741 pos_state = s->dict.pos & s->lzma.pos_mask;
742
743 if (!rc_bit(&s->rc, &s->lzma.is_match[
744 s->lzma.state][pos_state])) {
745 lzma_literal(s);
746 } else {
747 if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state]))
748 lzma_rep_match(s, pos_state);
749 else
750 lzma_match(s, pos_state);
751
752 if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0))
753 return false;
754 }
755 }
756
757
758
759
760
761 rc_normalize(&s->rc);
762
763 return true;
764}
765
766
767
768
769
770static void XZ_FUNC lzma_reset(struct xz_dec_lzma2 *s)
771{
772 uint16_t *probs;
773 size_t i;
774
775 s->lzma.state = STATE_LIT_LIT;
776 s->lzma.rep0 = 0;
777 s->lzma.rep1 = 0;
778 s->lzma.rep2 = 0;
779 s->lzma.rep3 = 0;
780
781
782
783
784
785
786
787
788
789
790 probs = s->lzma.is_match[0];
791 for (i = 0; i < PROBS_TOTAL; ++i)
792 probs[i] = RC_BIT_MODEL_TOTAL / 2;
793
794 rc_reset(&s->rc);
795}
796
797
798
799
800
801
802static bool XZ_FUNC lzma_props(struct xz_dec_lzma2 *s, uint8_t props)
803{
804 if (props > (4 * 5 + 4) * 9 + 8)
805 return false;
806
807 s->lzma.pos_mask = 0;
808 while (props >= 9 * 5) {
809 props -= 9 * 5;
810 ++s->lzma.pos_mask;
811 }
812
813 s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1;
814
815 s->lzma.literal_pos_mask = 0;
816 while (props >= 9) {
817 props -= 9;
818 ++s->lzma.literal_pos_mask;
819 }
820
821 s->lzma.lc = props;
822
823 if (s->lzma.lc + s->lzma.literal_pos_mask > 4)
824 return false;
825
826 s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1;
827
828 lzma_reset(s);
829
830 return true;
831}
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849static bool XZ_FUNC lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
850{
851 size_t in_avail;
852 uint32_t tmp;
853
854 in_avail = b->in_size - b->in_pos;
855 if (s->temp.size > 0 || s->lzma2.compressed == 0) {
856 tmp = 2 * LZMA_IN_REQUIRED - s->temp.size;
857 if (tmp > s->lzma2.compressed - s->temp.size)
858 tmp = s->lzma2.compressed - s->temp.size;
859 if (tmp > in_avail)
860 tmp = in_avail;
861
862 memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp);
863
864 if (s->temp.size + tmp == s->lzma2.compressed) {
865 memzero(s->temp.buf + s->temp.size + tmp,
866 sizeof(s->temp.buf)
867 - s->temp.size - tmp);
868 s->rc.in_limit = s->temp.size + tmp;
869 } else if (s->temp.size + tmp < LZMA_IN_REQUIRED) {
870 s->temp.size += tmp;
871 b->in_pos += tmp;
872 return true;
873 } else {
874 s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED;
875 }
876
877 s->rc.in = s->temp.buf;
878 s->rc.in_pos = 0;
879
880 if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp)
881 return false;
882
883 s->lzma2.compressed -= s->rc.in_pos;
884
885 if (s->rc.in_pos < s->temp.size) {
886 s->temp.size -= s->rc.in_pos;
887 memmove(s->temp.buf, s->temp.buf + s->rc.in_pos,
888 s->temp.size);
889 return true;
890 }
891
892 b->in_pos += s->rc.in_pos - s->temp.size;
893 s->temp.size = 0;
894 }
895
896 in_avail = b->in_size - b->in_pos;
897 if (in_avail >= LZMA_IN_REQUIRED) {
898 s->rc.in = b->in;
899 s->rc.in_pos = b->in_pos;
900
901 if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED)
902 s->rc.in_limit = b->in_pos + s->lzma2.compressed;
903 else
904 s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED;
905
906 if (!lzma_main(s))
907 return false;
908
909 in_avail = s->rc.in_pos - b->in_pos;
910 if (in_avail > s->lzma2.compressed)
911 return false;
912
913 s->lzma2.compressed -= in_avail;
914 b->in_pos = s->rc.in_pos;
915 }
916
917 in_avail = b->in_size - b->in_pos;
918 if (in_avail < LZMA_IN_REQUIRED) {
919 if (in_avail > s->lzma2.compressed)
920 in_avail = s->lzma2.compressed;
921
922 memcpy(s->temp.buf, b->in + b->in_pos, in_avail);
923 s->temp.size = in_avail;
924 b->in_pos += in_avail;
925 }
926
927 return true;
928}
929
930
931
932
933
934XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run(
935 struct xz_dec_lzma2 *s, struct xz_buf *b)
936{
937 uint32_t tmp;
938
939 while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN) {
940 switch (s->lzma2.sequence) {
941 case SEQ_CONTROL:
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973 tmp = b->in[b->in_pos++];
974
975 if (tmp >= 0xE0 || tmp == 0x01) {
976 s->lzma2.need_props = true;
977 s->lzma2.need_dict_reset = false;
978 dict_reset(&s->dict, b);
979 } else if (s->lzma2.need_dict_reset) {
980 return XZ_DATA_ERROR;
981 }
982
983 if (tmp >= 0x80) {
984 s->lzma2.uncompressed = (tmp & 0x1F) << 16;
985 s->lzma2.sequence = SEQ_UNCOMPRESSED_1;
986
987 if (tmp >= 0xC0) {
988
989
990
991
992
993 s->lzma2.need_props = false;
994 s->lzma2.next_sequence
995 = SEQ_PROPERTIES;
996
997 } else if (s->lzma2.need_props) {
998 return XZ_DATA_ERROR;
999
1000 } else {
1001 s->lzma2.next_sequence
1002 = SEQ_LZMA_PREPARE;
1003 if (tmp >= 0xA0)
1004 lzma_reset(s);
1005 }
1006 } else {
1007 if (tmp == 0x00)
1008 return XZ_STREAM_END;
1009
1010 if (tmp > 0x02)
1011 return XZ_DATA_ERROR;
1012
1013 s->lzma2.sequence = SEQ_COMPRESSED_0;
1014 s->lzma2.next_sequence = SEQ_COPY;
1015 }
1016
1017 break;
1018
1019 case SEQ_UNCOMPRESSED_1:
1020 s->lzma2.uncompressed
1021 += (uint32_t)b->in[b->in_pos++] << 8;
1022 s->lzma2.sequence = SEQ_UNCOMPRESSED_2;
1023 break;
1024
1025 case SEQ_UNCOMPRESSED_2:
1026 s->lzma2.uncompressed
1027 += (uint32_t)b->in[b->in_pos++] + 1;
1028 s->lzma2.sequence = SEQ_COMPRESSED_0;
1029 break;
1030
1031 case SEQ_COMPRESSED_0:
1032 s->lzma2.compressed
1033 = (uint32_t)b->in[b->in_pos++] << 8;
1034 s->lzma2.sequence = SEQ_COMPRESSED_1;
1035 break;
1036
1037 case SEQ_COMPRESSED_1:
1038 s->lzma2.compressed
1039 += (uint32_t)b->in[b->in_pos++] + 1;
1040 s->lzma2.sequence = s->lzma2.next_sequence;
1041 break;
1042
1043 case SEQ_PROPERTIES:
1044 if (!lzma_props(s, b->in[b->in_pos++]))
1045 return XZ_DATA_ERROR;
1046
1047 s->lzma2.sequence = SEQ_LZMA_PREPARE;
1048
1049 case SEQ_LZMA_PREPARE:
1050 if (s->lzma2.compressed < RC_INIT_BYTES)
1051 return XZ_DATA_ERROR;
1052
1053 if (!rc_read_init(&s->rc, b))
1054 return XZ_OK;
1055
1056 s->lzma2.compressed -= RC_INIT_BYTES;
1057 s->lzma2.sequence = SEQ_LZMA_RUN;
1058
1059 case SEQ_LZMA_RUN:
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069 dict_limit(&s->dict, min_t(size_t,
1070 b->out_size - b->out_pos,
1071 s->lzma2.uncompressed));
1072 if (!lzma2_lzma(s, b))
1073 return XZ_DATA_ERROR;
1074
1075 s->lzma2.uncompressed -= dict_flush(&s->dict, b);
1076
1077 if (s->lzma2.uncompressed == 0) {
1078 if (s->lzma2.compressed > 0 || s->lzma.len > 0
1079 || !rc_is_finished(&s->rc))
1080 return XZ_DATA_ERROR;
1081
1082 rc_reset(&s->rc);
1083 s->lzma2.sequence = SEQ_CONTROL;
1084
1085 } else if (b->out_pos == b->out_size
1086 || (b->in_pos == b->in_size
1087 && s->temp.size
1088 < s->lzma2.compressed)) {
1089 return XZ_OK;
1090 }
1091
1092 break;
1093
1094 case SEQ_COPY:
1095 dict_uncompressed(&s->dict, b, &s->lzma2.compressed);
1096 if (s->lzma2.compressed > 0)
1097 return XZ_OK;
1098
1099 s->lzma2.sequence = SEQ_CONTROL;
1100 break;
1101 }
1102 }
1103
1104 return XZ_OK;
1105}
1106
1107XZ_EXTERN struct xz_dec_lzma2 * XZ_FUNC xz_dec_lzma2_create(
1108 enum xz_mode mode, uint32_t dict_max)
1109{
1110 struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL);
1111 if (s == NULL)
1112 return NULL;
1113
1114 s->dict.mode = mode;
1115 s->dict.size_max = dict_max;
1116
1117 if (DEC_IS_PREALLOC(mode)) {
1118 s->dict.buf = vmalloc(dict_max);
1119 if (s->dict.buf == NULL) {
1120 kfree(s);
1121 return NULL;
1122 }
1123 } else if (DEC_IS_DYNALLOC(mode)) {
1124 s->dict.buf = NULL;
1125 s->dict.allocated = 0;
1126 }
1127
1128 return s;
1129}
1130
1131XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_lzma2_reset(
1132 struct xz_dec_lzma2 *s, uint8_t props)
1133{
1134
1135 if (props > 39)
1136 return XZ_OPTIONS_ERROR;
1137
1138 s->dict.size = 2 + (props & 1);
1139 s->dict.size <<= (props >> 1) + 11;
1140
1141 if (DEC_IS_MULTI(s->dict.mode)) {
1142 if (s->dict.size > s->dict.size_max)
1143 return XZ_MEMLIMIT_ERROR;
1144
1145 s->dict.end = s->dict.size;
1146
1147 if (DEC_IS_DYNALLOC(s->dict.mode)) {
1148 if (s->dict.allocated < s->dict.size) {
1149 vfree(s->dict.buf);
1150 s->dict.buf = vmalloc(s->dict.size);
1151 if (s->dict.buf == NULL) {
1152 s->dict.allocated = 0;
1153 return XZ_MEM_ERROR;
1154 }
1155 }
1156 }
1157 }
1158
1159 s->lzma.len = 0;
1160
1161 s->lzma2.sequence = SEQ_CONTROL;
1162 s->lzma2.need_dict_reset = true;
1163
1164 s->temp.size = 0;
1165
1166 return XZ_OK;
1167}
1168
1169XZ_EXTERN void XZ_FUNC xz_dec_lzma2_end(struct xz_dec_lzma2 *s)
1170{
1171 if (DEC_IS_MULTI(s->dict.mode))
1172 vfree(s->dict.buf);
1173
1174 kfree(s);
1175}
1176