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