OLD | NEW |
1 /////////////////////////////////////////////////////////////////////////////// | 1 /////////////////////////////////////////////////////////////////////////////// |
2 // | 2 // |
3 /// \file alone_decoder.c | 3 /// \file alone_decoder.c |
4 /// \brief Decoder for LZMA_Alone files | 4 /// \brief Decoder for LZMA_Alone files |
5 // | 5 // |
6 // Author: Lasse Collin | 6 // Author: Lasse Collin |
7 // | 7 // |
8 // This file has been put into the public domain. | 8 // This file has been put into the public domain. |
9 // You can do whatever you want with this file. | 9 // You can do whatever you want with this file. |
10 // | 10 // |
11 /////////////////////////////////////////////////////////////////////////////// | 11 /////////////////////////////////////////////////////////////////////////////// |
12 | 12 |
13 #include "alone_decoder.h" | 13 #include "alone_decoder.h" |
14 #include "lzma_decoder.h" | 14 #include "lzma_decoder.h" |
15 #include "lz_decoder.h" | 15 #include "lz_decoder.h" |
16 | 16 |
17 | 17 |
18 struct lzma_coder_s { | 18 struct lzma_coder_s { |
19 lzma_next_coder next; | 19 lzma_next_coder next; |
20 | 20 |
21 enum { | 21 enum { |
22 SEQ_PROPERTIES, | 22 SEQ_PROPERTIES, |
23 SEQ_DICTIONARY_SIZE, | 23 SEQ_DICTIONARY_SIZE, |
24 SEQ_UNCOMPRESSED_SIZE, | 24 SEQ_UNCOMPRESSED_SIZE, |
25 SEQ_CODER_INIT, | 25 SEQ_CODER_INIT, |
26 SEQ_CODE, | 26 SEQ_CODE, |
27 } sequence; | 27 } sequence; |
28 | 28 |
| 29 /// If true, reject files that are unlikely to be .lzma files. |
| 30 /// If false, more non-.lzma files get accepted and will give |
| 31 /// LZMA_DATA_ERROR either immediately or after a few output bytes. |
| 32 bool picky; |
| 33 |
29 /// Position in the header fields | 34 /// Position in the header fields |
30 size_t pos; | 35 size_t pos; |
31 | 36 |
32 /// Uncompressed size decoded from the header | 37 /// Uncompressed size decoded from the header |
33 lzma_vli uncompressed_size; | 38 lzma_vli uncompressed_size; |
34 | 39 |
35 /// Memory usage limit | 40 /// Memory usage limit |
36 uint64_t memlimit; | 41 uint64_t memlimit; |
37 | 42 |
38 /// Amount of memory actually needed (only an estimate) | 43 /// Amount of memory actually needed (only an estimate) |
(...skipping 22 matching lines...) Expand all Loading... |
61 | 66 |
62 coder->sequence = SEQ_DICTIONARY_SIZE; | 67 coder->sequence = SEQ_DICTIONARY_SIZE; |
63 ++*in_pos; | 68 ++*in_pos; |
64 break; | 69 break; |
65 | 70 |
66 case SEQ_DICTIONARY_SIZE: | 71 case SEQ_DICTIONARY_SIZE: |
67 coder->options.dict_size | 72 coder->options.dict_size |
68 |= (size_t)(in[*in_pos]) << (coder->pos * 8); | 73 |= (size_t)(in[*in_pos]) << (coder->pos * 8); |
69 | 74 |
70 if (++coder->pos == 4) { | 75 if (++coder->pos == 4) { |
71 » » » if (coder->options.dict_size != UINT32_MAX) { | 76 » » » if (coder->picky && coder->options.dict_size |
| 77 » » » » » != UINT32_MAX) { |
72 // A hack to ditch tons of false positives: | 78 // A hack to ditch tons of false positives: |
73 // We allow only dictionary sizes that are | 79 // We allow only dictionary sizes that are |
74 // 2^n or 2^n + 2^(n-1). LZMA_Alone created | 80 // 2^n or 2^n + 2^(n-1). LZMA_Alone created |
75 // only files with 2^n, but accepts any | 81 // only files with 2^n, but accepts any |
76 » » » » // dictionary size. If someone complains, this | 82 » » » » // dictionary size. |
77 » » » » // will be reconsidered. | |
78 uint32_t d = coder->options.dict_size - 1; | 83 uint32_t d = coder->options.dict_size - 1; |
79 d |= d >> 2; | 84 d |= d >> 2; |
80 d |= d >> 3; | 85 d |= d >> 3; |
81 d |= d >> 4; | 86 d |= d >> 4; |
82 d |= d >> 8; | 87 d |= d >> 8; |
83 d |= d >> 16; | 88 d |= d >> 16; |
84 ++d; | 89 ++d; |
85 | 90 |
86 if (d != coder->options.dict_size) | 91 if (d != coder->options.dict_size) |
87 return LZMA_FORMAT_ERROR; | 92 return LZMA_FORMAT_ERROR; |
88 } | 93 } |
89 | 94 |
90 coder->pos = 0; | 95 coder->pos = 0; |
91 coder->sequence = SEQ_UNCOMPRESSED_SIZE; | 96 coder->sequence = SEQ_UNCOMPRESSED_SIZE; |
92 } | 97 } |
93 | 98 |
94 ++*in_pos; | 99 ++*in_pos; |
95 break; | 100 break; |
96 | 101 |
97 case SEQ_UNCOMPRESSED_SIZE: | 102 case SEQ_UNCOMPRESSED_SIZE: |
98 coder->uncompressed_size | 103 coder->uncompressed_size |
99 |= (lzma_vli)(in[*in_pos]) << (coder->pos * 8); | 104 |= (lzma_vli)(in[*in_pos]) << (coder->pos * 8); |
100 ++*in_pos; | 105 ++*in_pos; |
101 if (++coder->pos < 8) | 106 if (++coder->pos < 8) |
102 break; | 107 break; |
103 | 108 |
104 // Another hack to ditch false positives: Assume that | 109 // Another hack to ditch false positives: Assume that |
105 // if the uncompressed size is known, it must be less | 110 // if the uncompressed size is known, it must be less |
106 » » // than 256 GiB. Again, if someone complains, this | 111 » » // than 256 GiB. |
107 » » // will be reconsidered. | 112 » » if (coder->picky |
108 » » if (coder->uncompressed_size != LZMA_VLI_UNKNOWN | 113 » » » » && coder->uncompressed_size != LZMA_VLI_UNKNOWN |
109 && coder->uncompressed_size | 114 && coder->uncompressed_size |
110 >= (LZMA_VLI_C(1) << 38)) | 115 >= (LZMA_VLI_C(1) << 38)) |
111 return LZMA_FORMAT_ERROR; | 116 return LZMA_FORMAT_ERROR; |
112 | 117 |
113 // Calculate the memory usage so that it is ready | 118 // Calculate the memory usage so that it is ready |
114 // for SEQ_CODER_INIT. | 119 // for SEQ_CODER_INIT. |
115 coder->memusage = lzma_lzma_decoder_memusage(&coder->options) | 120 coder->memusage = lzma_lzma_decoder_memusage(&coder->options) |
116 + LZMA_MEMUSAGE_BASE; | 121 + LZMA_MEMUSAGE_BASE; |
117 | 122 |
118 coder->pos = 0; | 123 coder->pos = 0; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 | 187 |
183 coder->memlimit = new_memlimit; | 188 coder->memlimit = new_memlimit; |
184 } | 189 } |
185 | 190 |
186 return LZMA_OK; | 191 return LZMA_OK; |
187 } | 192 } |
188 | 193 |
189 | 194 |
190 extern lzma_ret | 195 extern lzma_ret |
191 lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator, | 196 lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator, |
192 » » uint64_t memlimit) | 197 » » uint64_t memlimit, bool picky) |
193 { | 198 { |
194 lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator); | 199 lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator); |
195 | 200 |
196 if (memlimit == 0) | 201 if (memlimit == 0) |
197 return LZMA_PROG_ERROR; | 202 return LZMA_PROG_ERROR; |
198 | 203 |
199 if (next->coder == NULL) { | 204 if (next->coder == NULL) { |
200 next->coder = lzma_alloc(sizeof(lzma_coder), allocator); | 205 next->coder = lzma_alloc(sizeof(lzma_coder), allocator); |
201 if (next->coder == NULL) | 206 if (next->coder == NULL) |
202 return LZMA_MEM_ERROR; | 207 return LZMA_MEM_ERROR; |
203 | 208 |
204 next->code = &alone_decode; | 209 next->code = &alone_decode; |
205 next->end = &alone_decoder_end; | 210 next->end = &alone_decoder_end; |
206 next->memconfig = &alone_decoder_memconfig; | 211 next->memconfig = &alone_decoder_memconfig; |
207 next->coder->next = LZMA_NEXT_CODER_INIT; | 212 next->coder->next = LZMA_NEXT_CODER_INIT; |
208 } | 213 } |
209 | 214 |
210 next->coder->sequence = SEQ_PROPERTIES; | 215 next->coder->sequence = SEQ_PROPERTIES; |
| 216 next->coder->picky = picky; |
211 next->coder->pos = 0; | 217 next->coder->pos = 0; |
212 next->coder->options.dict_size = 0; | 218 next->coder->options.dict_size = 0; |
213 next->coder->options.preset_dict = NULL; | 219 next->coder->options.preset_dict = NULL; |
214 next->coder->options.preset_dict_size = 0; | 220 next->coder->options.preset_dict_size = 0; |
215 next->coder->uncompressed_size = 0; | 221 next->coder->uncompressed_size = 0; |
216 next->coder->memlimit = memlimit; | 222 next->coder->memlimit = memlimit; |
217 next->coder->memusage = LZMA_MEMUSAGE_BASE; | 223 next->coder->memusage = LZMA_MEMUSAGE_BASE; |
218 | 224 |
219 return LZMA_OK; | 225 return LZMA_OK; |
220 } | 226 } |
221 | 227 |
222 | 228 |
223 extern LZMA_API(lzma_ret) | 229 extern LZMA_API(lzma_ret) |
224 lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit) | 230 lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit) |
225 { | 231 { |
226 » lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit); | 232 » lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit, false); |
227 | 233 |
228 strm->internal->supported_actions[LZMA_RUN] = true; | 234 strm->internal->supported_actions[LZMA_RUN] = true; |
229 strm->internal->supported_actions[LZMA_FINISH] = true; | 235 strm->internal->supported_actions[LZMA_FINISH] = true; |
230 | 236 |
231 return LZMA_OK; | 237 return LZMA_OK; |
232 } | 238 } |
OLD | NEW |