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