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