/src/lzma-fuzz/sdk/C/7zDec.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* 7zDec.c -- Decoding from 7z folder |
2 | | 2019-02-02 : Igor Pavlov : Public domain */ |
3 | | |
4 | | #include "Precomp.h" |
5 | | |
6 | | #include <string.h> |
7 | | |
8 | | /* #define _7ZIP_PPMD_SUPPPORT */ |
9 | | |
10 | | #include "7z.h" |
11 | | #include "7zCrc.h" |
12 | | |
13 | | #include "Bcj2.h" |
14 | | #include "Bra.h" |
15 | | #include "CpuArch.h" |
16 | | #include "Delta.h" |
17 | | #include "LzmaDec.h" |
18 | | #include "Lzma2Dec.h" |
19 | | #ifdef _7ZIP_PPMD_SUPPPORT |
20 | | #include "Ppmd7.h" |
21 | | #endif |
22 | | |
23 | 4.89k | #define k_Copy 0 |
24 | 50 | #define k_Delta 3 |
25 | 9.91k | #define k_LZMA2 0x21 |
26 | 13.0k | #define k_LZMA 0x30101 |
27 | 21 | #define k_BCJ 0x3030103 |
28 | 318 | #define k_BCJ2 0x303011B |
29 | 44 | #define k_PPC 0x3030205 |
30 | 60 | #define k_IA64 0x3030401 |
31 | 111 | #define k_ARM 0x3030501 |
32 | 115 | #define k_ARMT 0x3030701 |
33 | 97 | #define k_SPARC 0x3030805 |
34 | | |
35 | | |
36 | | #ifdef _7ZIP_PPMD_SUPPPORT |
37 | | |
38 | 10.0k | #define k_PPMD 0x30401 |
39 | | |
40 | | typedef struct |
41 | | { |
42 | | IByteIn vt; |
43 | | const Byte *cur; |
44 | | const Byte *end; |
45 | | const Byte *begin; |
46 | | UInt64 processed; |
47 | | BoolInt extra; |
48 | | SRes res; |
49 | | const ILookInStream *inStream; |
50 | | } CByteInToLook; |
51 | | |
52 | | static Byte ReadByte(const IByteIn *pp) |
53 | 10.7k | { |
54 | 10.7k | CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt); |
55 | 10.7k | if (p->cur != p->end) |
56 | 10.4k | return *p->cur++; |
57 | 281 | if (p->res == SZ_OK) |
58 | 281 | { |
59 | 281 | size_t size = p->cur - p->begin; |
60 | 281 | p->processed += size; |
61 | 281 | p->res = ILookInStream_Skip(p->inStream, size); |
62 | 281 | size = (1 << 25); |
63 | 281 | p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size); |
64 | 281 | p->cur = p->begin; |
65 | 281 | p->end = p->begin + size; |
66 | 281 | if (size != 0) |
67 | 281 | return *p->cur++;; |
68 | 0 | } |
69 | 0 | p->extra = True; |
70 | 0 | return 0; |
71 | 281 | } |
72 | | |
73 | | static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream, |
74 | | Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) |
75 | 281 | { |
76 | 281 | CPpmd7 ppmd; |
77 | 281 | CByteInToLook s; |
78 | 281 | SRes res = SZ_OK; |
79 | | |
80 | 281 | s.vt.Read = ReadByte; |
81 | 281 | s.inStream = inStream; |
82 | 281 | s.begin = s.end = s.cur = NULL; |
83 | 281 | s.extra = False; |
84 | 281 | s.res = SZ_OK; |
85 | 281 | s.processed = 0; |
86 | | |
87 | 281 | if (propsSize != 5) |
88 | 0 | return SZ_ERROR_UNSUPPORTED; |
89 | | |
90 | 281 | { |
91 | 281 | unsigned order = props[0]; |
92 | 281 | UInt32 memSize = GetUi32(props + 1); |
93 | 281 | if (order < PPMD7_MIN_ORDER || |
94 | 281 | order > PPMD7_MAX_ORDER || |
95 | 281 | memSize < PPMD7_MIN_MEM_SIZE || |
96 | 281 | memSize > PPMD7_MAX_MEM_SIZE) |
97 | 0 | return SZ_ERROR_UNSUPPORTED; |
98 | 281 | Ppmd7_Construct(&ppmd); |
99 | 281 | if (!Ppmd7_Alloc(&ppmd, memSize, allocMain)) |
100 | 0 | return SZ_ERROR_MEM; |
101 | 281 | Ppmd7_Init(&ppmd, order); |
102 | 281 | } |
103 | 0 | { |
104 | 281 | CPpmd7z_RangeDec rc; |
105 | 281 | Ppmd7z_RangeDec_CreateVTable(&rc); |
106 | 281 | rc.Stream = &s.vt; |
107 | 281 | if (!Ppmd7z_RangeDec_Init(&rc)) |
108 | 3 | res = SZ_ERROR_DATA; |
109 | 278 | else if (s.extra) |
110 | 0 | res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); |
111 | 278 | else |
112 | 278 | { |
113 | 278 | SizeT i; |
114 | 16.1k | for (i = 0; i < outSize; i++) |
115 | 15.9k | { |
116 | 15.9k | int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt); |
117 | 15.9k | if (s.extra || sym < 0) |
118 | 47 | break; |
119 | 15.9k | outBuffer[i] = (Byte)sym; |
120 | 15.9k | } |
121 | 278 | if (i != outSize) |
122 | 47 | res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA); |
123 | 231 | else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc)) |
124 | 229 | res = SZ_ERROR_DATA; |
125 | 278 | } |
126 | 281 | } |
127 | 281 | Ppmd7_Free(&ppmd, allocMain); |
128 | 281 | return res; |
129 | 281 | } |
130 | | |
131 | | #endif |
132 | | |
133 | | |
134 | | static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, |
135 | | Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) |
136 | 4.10k | { |
137 | 4.10k | CLzmaDec state; |
138 | 4.10k | SRes res = SZ_OK; |
139 | | |
140 | 4.10k | LzmaDec_Construct(&state); |
141 | 4.10k | RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain)); |
142 | 4.10k | state.dic = outBuffer; |
143 | 4.10k | state.dicBufSize = outSize; |
144 | 4.10k | LzmaDec_Init(&state); |
145 | | |
146 | 4.10k | for (;;) |
147 | 6.42k | { |
148 | 6.42k | const void *inBuf = NULL; |
149 | 6.42k | size_t lookahead = (1 << 18); |
150 | 6.42k | if (lookahead > inSize) |
151 | 6.42k | lookahead = (size_t)inSize; |
152 | 6.42k | res = ILookInStream_Look(inStream, &inBuf, &lookahead); |
153 | 6.42k | if (res != SZ_OK) |
154 | 0 | break; |
155 | | |
156 | 6.42k | { |
157 | 6.42k | SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos; |
158 | 6.42k | ELzmaStatus status; |
159 | 6.42k | res = LzmaDec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status); |
160 | 6.42k | lookahead -= inProcessed; |
161 | 6.42k | inSize -= inProcessed; |
162 | 6.42k | if (res != SZ_OK) |
163 | 871 | break; |
164 | | |
165 | 5.55k | if (status == LZMA_STATUS_FINISHED_WITH_MARK) |
166 | 3 | { |
167 | 3 | if (outSize != state.dicPos || inSize != 0) |
168 | 3 | res = SZ_ERROR_DATA; |
169 | 3 | break; |
170 | 3 | } |
171 | | |
172 | 5.55k | if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) |
173 | 900 | break; |
174 | | |
175 | 4.65k | if (inProcessed == 0 && dicPos == state.dicPos) |
176 | 2.33k | { |
177 | 2.33k | res = SZ_ERROR_DATA; |
178 | 2.33k | break; |
179 | 2.33k | } |
180 | | |
181 | 2.32k | res = ILookInStream_Skip(inStream, inProcessed); |
182 | 2.32k | if (res != SZ_OK) |
183 | 0 | break; |
184 | 2.32k | } |
185 | 2.32k | } |
186 | | |
187 | 4.10k | LzmaDec_FreeProbs(&state, allocMain); |
188 | 4.10k | return res; |
189 | 4.10k | } |
190 | | |
191 | | |
192 | | #ifndef _7Z_NO_METHOD_LZMA2 |
193 | | |
194 | | static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, |
195 | | Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) |
196 | 459 | { |
197 | 459 | CLzma2Dec state; |
198 | 459 | SRes res = SZ_OK; |
199 | | |
200 | 459 | Lzma2Dec_Construct(&state); |
201 | 459 | if (propsSize != 1) |
202 | 0 | return SZ_ERROR_DATA; |
203 | 459 | RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain)); |
204 | 459 | state.decoder.dic = outBuffer; |
205 | 459 | state.decoder.dicBufSize = outSize; |
206 | 459 | Lzma2Dec_Init(&state); |
207 | | |
208 | 459 | for (;;) |
209 | 592 | { |
210 | 592 | const void *inBuf = NULL; |
211 | 592 | size_t lookahead = (1 << 18); |
212 | 592 | if (lookahead > inSize) |
213 | 592 | lookahead = (size_t)inSize; |
214 | 592 | res = ILookInStream_Look(inStream, &inBuf, &lookahead); |
215 | 592 | if (res != SZ_OK) |
216 | 0 | break; |
217 | | |
218 | 592 | { |
219 | 592 | SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos; |
220 | 592 | ELzmaStatus status; |
221 | 592 | res = Lzma2Dec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status); |
222 | 592 | lookahead -= inProcessed; |
223 | 592 | inSize -= inProcessed; |
224 | 592 | if (res != SZ_OK) |
225 | 185 | break; |
226 | | |
227 | 407 | if (status == LZMA_STATUS_FINISHED_WITH_MARK) |
228 | 141 | { |
229 | 141 | if (outSize != state.decoder.dicPos || inSize != 0) |
230 | 18 | res = SZ_ERROR_DATA; |
231 | 141 | break; |
232 | 141 | } |
233 | | |
234 | 266 | if (inProcessed == 0 && dicPos == state.decoder.dicPos) |
235 | 133 | { |
236 | 133 | res = SZ_ERROR_DATA; |
237 | 133 | break; |
238 | 133 | } |
239 | | |
240 | 133 | res = ILookInStream_Skip(inStream, inProcessed); |
241 | 133 | if (res != SZ_OK) |
242 | 0 | break; |
243 | 133 | } |
244 | 133 | } |
245 | | |
246 | 459 | Lzma2Dec_FreeProbs(&state, allocMain); |
247 | 459 | return res; |
248 | 459 | } |
249 | | |
250 | | #endif |
251 | | |
252 | | |
253 | | static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) |
254 | 96 | { |
255 | 192 | while (inSize > 0) |
256 | 96 | { |
257 | 96 | const void *inBuf; |
258 | 96 | size_t curSize = (1 << 18); |
259 | 96 | if (curSize > inSize) |
260 | 96 | curSize = (size_t)inSize; |
261 | 96 | RINOK(ILookInStream_Look(inStream, &inBuf, &curSize)); |
262 | 96 | if (curSize == 0) |
263 | 0 | return SZ_ERROR_INPUT_EOF; |
264 | 96 | memcpy(outBuffer, inBuf, curSize); |
265 | 96 | outBuffer += curSize; |
266 | 96 | inSize -= curSize; |
267 | 96 | RINOK(ILookInStream_Skip(inStream, curSize)); |
268 | 96 | } |
269 | 96 | return SZ_OK; |
270 | 96 | } |
271 | | |
272 | | static BoolInt IS_MAIN_METHOD(UInt32 m) |
273 | 9.86k | { |
274 | 9.86k | switch (m) |
275 | 9.86k | { |
276 | 32 | case k_Copy: |
277 | 8.24k | case k_LZMA: |
278 | 8.24k | #ifndef _7Z_NO_METHOD_LZMA2 |
279 | 9.17k | case k_LZMA2: |
280 | 9.17k | #endif |
281 | 9.17k | #ifdef _7ZIP_PPMD_SUPPPORT |
282 | 9.73k | case k_PPMD: |
283 | 9.73k | #endif |
284 | 9.73k | return True; |
285 | 9.86k | } |
286 | 130 | return False; |
287 | 9.86k | } |
288 | | |
289 | | static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c) |
290 | 4.87k | { |
291 | 4.87k | return |
292 | 4.87k | c->NumStreams == 1 |
293 | | /* && c->MethodID <= (UInt32)0xFFFFFFFF */ |
294 | 4.87k | && IS_MAIN_METHOD((UInt32)c->MethodID); |
295 | 4.87k | } |
296 | | |
297 | 94 | #define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4) |
298 | | |
299 | | static SRes CheckSupportedFolder(const CSzFolder *f) |
300 | 4.68k | { |
301 | 4.68k | if (f->NumCoders < 1 || f->NumCoders > 4) |
302 | 0 | return SZ_ERROR_UNSUPPORTED; |
303 | 4.68k | if (!IS_SUPPORTED_CODER(&f->Coders[0])) |
304 | 0 | return SZ_ERROR_UNSUPPORTED; |
305 | 4.68k | if (f->NumCoders == 1) |
306 | 4.48k | { |
307 | 4.48k | if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0) |
308 | 0 | return SZ_ERROR_UNSUPPORTED; |
309 | 4.48k | return SZ_OK; |
310 | 4.48k | } |
311 | | |
312 | | |
313 | 203 | #ifndef _7Z_NO_METHODS_FILTERS |
314 | | |
315 | 203 | if (f->NumCoders == 2) |
316 | 109 | { |
317 | 109 | const CSzCoderInfo *c = &f->Coders[1]; |
318 | 109 | if ( |
319 | | /* c->MethodID > (UInt32)0xFFFFFFFF || */ |
320 | 109 | c->NumStreams != 1 |
321 | 109 | || f->NumPackStreams != 1 |
322 | 109 | || f->PackStreams[0] != 0 |
323 | 109 | || f->NumBonds != 1 |
324 | 109 | || f->Bonds[0].InIndex != 1 |
325 | 109 | || f->Bonds[0].OutIndex != 0) |
326 | 0 | return SZ_ERROR_UNSUPPORTED; |
327 | 109 | switch ((UInt32)c->MethodID) |
328 | 109 | { |
329 | 0 | case k_Delta: |
330 | 11 | case k_BCJ: |
331 | 34 | case k_PPC: |
332 | 47 | case k_IA64: |
333 | 94 | case k_SPARC: |
334 | 103 | case k_ARM: |
335 | 109 | case k_ARMT: |
336 | 109 | break; |
337 | 0 | default: |
338 | 0 | return SZ_ERROR_UNSUPPORTED; |
339 | 109 | } |
340 | 109 | return SZ_OK; |
341 | 109 | } |
342 | | |
343 | 94 | #endif |
344 | | |
345 | | |
346 | 94 | if (f->NumCoders == 4) |
347 | 94 | { |
348 | 94 | if (!IS_SUPPORTED_CODER(&f->Coders[1]) |
349 | 94 | || !IS_SUPPORTED_CODER(&f->Coders[2]) |
350 | 94 | || !IS_BCJ2(&f->Coders[3])) |
351 | 0 | return SZ_ERROR_UNSUPPORTED; |
352 | 94 | if (f->NumPackStreams != 4 |
353 | 94 | || f->PackStreams[0] != 2 |
354 | 94 | || f->PackStreams[1] != 6 |
355 | 94 | || f->PackStreams[2] != 1 |
356 | 94 | || f->PackStreams[3] != 0 |
357 | 94 | || f->NumBonds != 3 |
358 | 94 | || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0 |
359 | 94 | || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1 |
360 | 94 | || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2) |
361 | 0 | return SZ_ERROR_UNSUPPORTED; |
362 | 94 | return SZ_OK; |
363 | 94 | } |
364 | | |
365 | 0 | return SZ_ERROR_UNSUPPORTED; |
366 | 94 | } |
367 | | |
368 | 40 | #define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; |
369 | | |
370 | | static SRes SzFolder_Decode2(const CSzFolder *folder, |
371 | | const Byte *propsData, |
372 | | const UInt64 *unpackSizes, |
373 | | const UInt64 *packPositions, |
374 | | ILookInStream *inStream, UInt64 startPos, |
375 | | Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain, |
376 | | Byte *tempBuf[]) |
377 | 4.68k | { |
378 | 4.68k | UInt32 ci; |
379 | 4.68k | SizeT tempSizes[3] = { 0, 0, 0}; |
380 | 4.68k | SizeT tempSize3 = 0; |
381 | 4.68k | Byte *tempBuf3 = 0; |
382 | | |
383 | 4.68k | RINOK(CheckSupportedFolder(folder)); |
384 | | |
385 | 5.78k | for (ci = 0; ci < folder->NumCoders; ci++) |
386 | 4.99k | { |
387 | 4.99k | const CSzCoderInfo *coder = &folder->Coders[ci]; |
388 | | |
389 | 4.99k | if (IS_MAIN_METHOD((UInt32)coder->MethodID)) |
390 | 4.86k | { |
391 | 4.86k | UInt32 si = 0; |
392 | 4.86k | UInt64 offset; |
393 | 4.86k | UInt64 inSize; |
394 | 4.86k | Byte *outBufCur = outBuffer; |
395 | 4.86k | SizeT outSizeCur = outSize; |
396 | 4.86k | if (folder->NumCoders == 4) |
397 | 265 | { |
398 | 265 | UInt32 indices[] = { 3, 2, 0 }; |
399 | 265 | UInt64 unpackSize = unpackSizes[ci]; |
400 | 265 | si = indices[ci]; |
401 | 265 | if (ci < 2) |
402 | 183 | { |
403 | 183 | Byte *temp; |
404 | 183 | outSizeCur = (SizeT)unpackSize; |
405 | 183 | if (outSizeCur != unpackSize) |
406 | 0 | return SZ_ERROR_MEM; |
407 | 183 | temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur); |
408 | 183 | if (!temp && outSizeCur != 0) |
409 | 0 | return SZ_ERROR_MEM; |
410 | 183 | outBufCur = tempBuf[1 - ci] = temp; |
411 | 183 | tempSizes[1 - ci] = outSizeCur; |
412 | 183 | } |
413 | 82 | else if (ci == 2) |
414 | 82 | { |
415 | 82 | if (unpackSize > outSize) /* check it */ |
416 | 0 | return SZ_ERROR_PARAM; |
417 | 82 | tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); |
418 | 82 | tempSize3 = outSizeCur = (SizeT)unpackSize; |
419 | 82 | } |
420 | 0 | else |
421 | 0 | return SZ_ERROR_UNSUPPORTED; |
422 | 265 | } |
423 | 4.86k | offset = packPositions[si]; |
424 | 4.86k | inSize = packPositions[(size_t)si + 1] - offset; |
425 | 4.86k | RINOK(LookInStream_SeekTo(inStream, startPos + offset)); |
426 | | |
427 | 4.86k | if (coder->MethodID == k_Copy) |
428 | 16 | { |
429 | 16 | if (inSize != outSizeCur) /* check it */ |
430 | 0 | return SZ_ERROR_DATA; |
431 | 16 | RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); |
432 | 16 | } |
433 | 4.84k | else if (coder->MethodID == k_LZMA) |
434 | 4.10k | { |
435 | 4.10k | RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); |
436 | 900 | } |
437 | 740 | #ifndef _7Z_NO_METHOD_LZMA2 |
438 | 740 | else if (coder->MethodID == k_LZMA2) |
439 | 459 | { |
440 | 459 | RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); |
441 | 123 | } |
442 | 281 | #endif |
443 | 281 | #ifdef _7ZIP_PPMD_SUPPPORT |
444 | 281 | else if (coder->MethodID == k_PPMD) |
445 | 281 | { |
446 | 281 | RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); |
447 | 2 | } |
448 | 0 | #endif |
449 | 0 | else |
450 | 0 | return SZ_ERROR_UNSUPPORTED; |
451 | 4.86k | } |
452 | 130 | else if (coder->MethodID == k_BCJ2) |
453 | 80 | { |
454 | 80 | UInt64 offset = packPositions[1]; |
455 | 80 | UInt64 s3Size = packPositions[2] - offset; |
456 | | |
457 | 80 | if (ci != 3) |
458 | 0 | return SZ_ERROR_UNSUPPORTED; |
459 | | |
460 | 80 | tempSizes[2] = (SizeT)s3Size; |
461 | 80 | if (tempSizes[2] != s3Size) |
462 | 0 | return SZ_ERROR_MEM; |
463 | 80 | tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]); |
464 | 80 | if (!tempBuf[2] && tempSizes[2] != 0) |
465 | 0 | return SZ_ERROR_MEM; |
466 | | |
467 | 80 | RINOK(LookInStream_SeekTo(inStream, startPos + offset)); |
468 | 80 | RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2])); |
469 | | |
470 | 80 | if ((tempSizes[0] & 3) != 0 || |
471 | 80 | (tempSizes[1] & 3) != 0 || |
472 | 80 | tempSize3 + tempSizes[0] + tempSizes[1] != outSize) |
473 | 0 | return SZ_ERROR_DATA; |
474 | | |
475 | 80 | { |
476 | 80 | CBcj2Dec p; |
477 | | |
478 | 80 | p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3; |
479 | 80 | p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0]; |
480 | 80 | p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1]; |
481 | 80 | p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2]; |
482 | | |
483 | 80 | p.dest = outBuffer; |
484 | 80 | p.destLim = outBuffer + outSize; |
485 | | |
486 | 80 | Bcj2Dec_Init(&p); |
487 | 80 | RINOK(Bcj2Dec_Decode(&p)); |
488 | | |
489 | 76 | { |
490 | 76 | unsigned i; |
491 | 260 | for (i = 0; i < 4; i++) |
492 | 214 | if (p.bufs[i] != p.lims[i]) |
493 | 30 | return SZ_ERROR_DATA; |
494 | | |
495 | 46 | if (!Bcj2Dec_IsFinished(&p)) |
496 | 42 | return SZ_ERROR_DATA; |
497 | | |
498 | 4 | if (p.dest != p.destLim |
499 | 4 | || p.state != BCJ2_STREAM_MAIN) |
500 | 1 | return SZ_ERROR_DATA; |
501 | 4 | } |
502 | 4 | } |
503 | 4 | } |
504 | 50 | #ifndef _7Z_NO_METHODS_FILTERS |
505 | 50 | else if (ci == 1) |
506 | 50 | { |
507 | 50 | if (coder->MethodID == k_Delta) |
508 | 0 | { |
509 | 0 | if (coder->PropsSize != 1) |
510 | 0 | return SZ_ERROR_UNSUPPORTED; |
511 | 0 | { |
512 | 0 | Byte state[DELTA_STATE_SIZE]; |
513 | 0 | Delta_Init(state); |
514 | 0 | Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize); |
515 | 0 | } |
516 | 0 | } |
517 | 50 | else |
518 | 50 | { |
519 | 50 | if (coder->PropsSize != 0) |
520 | 0 | return SZ_ERROR_UNSUPPORTED; |
521 | 50 | switch (coder->MethodID) |
522 | 50 | { |
523 | 10 | case k_BCJ: |
524 | 10 | { |
525 | 10 | UInt32 state; |
526 | 10 | x86_Convert_Init(state); |
527 | 10 | x86_Convert(outBuffer, outSize, 0, &state, 0); |
528 | 10 | break; |
529 | 0 | } |
530 | 10 | CASE_BRA_CONV(PPC) |
531 | 13 | CASE_BRA_CONV(IA64) |
532 | 3 | CASE_BRA_CONV(SPARC) |
533 | 8 | CASE_BRA_CONV(ARM) |
534 | 6 | CASE_BRA_CONV(ARMT) |
535 | 0 | default: |
536 | 0 | return SZ_ERROR_UNSUPPORTED; |
537 | 50 | } |
538 | 50 | } |
539 | 50 | } |
540 | 0 | #endif |
541 | 0 | else |
542 | 0 | return SZ_ERROR_UNSUPPORTED; |
543 | 4.99k | } |
544 | | |
545 | 793 | return SZ_OK; |
546 | 4.68k | } |
547 | | |
548 | | |
549 | | SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, |
550 | | ILookInStream *inStream, UInt64 startPos, |
551 | | Byte *outBuffer, size_t outSize, |
552 | | ISzAllocPtr allocMain) |
553 | 4.68k | { |
554 | 4.68k | SRes res; |
555 | 4.68k | CSzFolder folder; |
556 | 4.68k | CSzData sd; |
557 | | |
558 | 4.68k | const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; |
559 | 4.68k | sd.Data = data; |
560 | 4.68k | sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex]; |
561 | | |
562 | 4.68k | res = SzGetNextFolderItem(&folder, &sd); |
563 | | |
564 | 4.68k | if (res != SZ_OK) |
565 | 0 | return res; |
566 | | |
567 | 4.68k | if (sd.Size != 0 |
568 | 4.68k | || folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex] |
569 | 4.68k | || outSize != SzAr_GetFolderUnpackSize(p, folderIndex)) |
570 | 0 | return SZ_ERROR_FAIL; |
571 | 4.68k | { |
572 | 4.68k | unsigned i; |
573 | 4.68k | Byte *tempBuf[3] = { 0, 0, 0}; |
574 | | |
575 | 4.68k | res = SzFolder_Decode2(&folder, data, |
576 | 4.68k | &p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]], |
577 | 4.68k | p->PackPositions + p->FoStartPackStreamIndex[folderIndex], |
578 | 4.68k | inStream, startPos, |
579 | 4.68k | outBuffer, (SizeT)outSize, allocMain, tempBuf); |
580 | | |
581 | 18.7k | for (i = 0; i < 3; i++) |
582 | 14.0k | ISzAlloc_Free(allocMain, tempBuf[i]); |
583 | | |
584 | 4.68k | if (res == SZ_OK) |
585 | 793 | if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex)) |
586 | 717 | if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex]) |
587 | 24 | res = SZ_ERROR_CRC; |
588 | | |
589 | 4.68k | return res; |
590 | 4.68k | } |
591 | 4.68k | } |