static SRes SzReadAndDecodePackedStreams2( ISeekInStream *inStream, CSzData *sd, ISeqOutStream *outStream, UInt64 baseOffset, CSzAr *p, UInt64 **unpackSizes, Byte **digestsDefined, UInt32 **digests, ISzAlloc *allocTemp) { CMemOutStream* memStream; UInt32 numUnpackStreams = 0; UInt64 dataStartPos; CSzFolder *folder; UInt64 unpackSize; SRes res; Int64 offset; RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, &numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp, allocTemp)); dataStartPos += baseOffset; if (p->NumFolders != 1) return SZ_ERROR_ARCHIVE; folder = p->Folders; unpackSize = SzFolder_GetUnpackSize(folder); offset = (Int64)dataStartPos; RINOK(inStream->Seek(inStream, &offset, SZ_SEEK_SET)); memStream = (CMemOutStream*)outStream; if (!Buf_Create((CBuf*)&memStream->data, (size_t)unpackSize, allocTemp)) return SZ_ERROR_MEM; res = SzFolder_Decode(folder, p->PackSizes, inStream, dataStartPos, outStream, (size_t)unpackSize, NULL, allocTemp); RINOK(res); if (folder->UnpackCRCDefined) if (CrcCalc(memStream->data, (size_t)unpackSize) != folder->UnpackCRC) return SZ_ERROR_CRC; return SZ_OK; }
static SRes SzReadAndDecodePackedStreams2( ILookInStream *inStream, CSzData *sd, CBuf *outBuffer, UInt64 baseOffset, CSzAr *p, UInt64 **unpackSizes, Byte **digestsDefined, UInt32 **digests, ISzAlloc *allocTemp) { UInt32 numUnpackStreams = 0; UInt64 dataStartPos; CSzFolder *folder; UInt64 unpackSize; SRes res; RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, &numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp, allocTemp)); dataStartPos += baseOffset; if (p->NumFolders != 1) return SZ_ERROR_ARCHIVE; folder = p->Folders; unpackSize = SzFolder_GetUnpackSize(folder); RINOK(LookInStream_SeekTo(inStream, dataStartPos)); if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) return SZ_ERROR_MEM; res = SzFolder_Decode(folder, p->PackSizes, inStream, dataStartPos, outBuffer->data, (size_t)unpackSize, allocTemp); RINOK(res); #ifdef _7ZIP_CRC_SUPPORT if (folder->UnpackCRCDefined) if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) return SZ_ERROR_CRC; #endif return SZ_OK; }
static SRes SzReadHeader2( CSzArEx *p, /* allocMain */ CSzData *sd, uint64_t **unpackSizes, /* allocTemp */ uint8_t **digestsDefined, /* allocTemp */ uint32_t **digests, /* allocTemp */ uint8_t **emptyStreamVector, /* allocTemp */ uint8_t **emptyFileVector, /* allocTemp */ uint8_t **lwtVector, /* allocTemp */ ISzAlloc *allocMain, ISzAlloc *allocTemp) { uint64_t type; uint32_t numUnpackStreams = 0; uint32_t numFiles = 0; CSzFileItem *files = 0; uint32_t numEmptyStreams = 0; uint32_t i; RINOK(SzReadID(sd, &type)); if (type == k7zIdArchiveProperties) { RINOK(SzReadArchiveProperties(sd)); RINOK(SzReadID(sd, &type)); } if (type == k7zIdMainStreamsInfo) { RINOK(SzReadStreamsInfo(sd, &p->dataPos, &p->db, &numUnpackStreams, unpackSizes, digestsDefined, digests, allocMain, allocTemp)); p->dataPos += p->startPosAfterHeader; RINOK(SzReadID(sd, &type)); } if (type == k7zIdEnd) return SZ_OK; if (type != k7zIdFilesInfo) return SZ_ERROR_ARCHIVE; RINOK(SzReadNumber32(sd, &numFiles)); p->db.NumFiles = numFiles; MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); p->db.Files = files; for (i = 0; i < numFiles; i++) SzFile_Init(files + i); for (;;) { uint64_t size; RINOK(SzReadID(sd, &type)); if (type == k7zIdEnd) break; RINOK(SzReadNumber(sd, &size)); if (size > sd->Size) return SZ_ERROR_ARCHIVE; if ((uint64_t)(int)type != type) { RINOK(SzSkeepDataSize(sd, size)); } else switch((int)type) { case k7zIdName: { size_t namesSize; RINOK(SzReadSwitch(sd)); namesSize = (size_t)size - 1; if ((namesSize & 1) != 0) return SZ_ERROR_ARCHIVE; if (!Buf_Create(&p->FileNames, namesSize, allocMain)) return SZ_ERROR_MEM; MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); memcpy(p->FileNames.data, sd->Data, namesSize); RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets)) RINOK(SzSkeepDataSize(sd, namesSize)); break; } case k7zIdEmptyStream: { RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); numEmptyStreams = 0; for (i = 0; i < numFiles; i++) if ((*emptyStreamVector)[i]) numEmptyStreams++; break; } case k7zIdEmptyFile: { RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); break; } case k7zIdWinAttributes: { RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); RINOK(SzReadSwitch(sd)); for (i = 0; i < numFiles; i++) { CSzFileItem *f = &files[i]; uint8_t defined = (*lwtVector)[i]; f->AttribDefined = defined; f->Attrib = 0; if (defined) { RINOK(SzReaduint32_t(sd, &f->Attrib)); } } IAlloc_Free(allocTemp, *lwtVector); *lwtVector = NULL; break; } case k7zIdMTime: { RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); RINOK(SzReadSwitch(sd)); for (i = 0; i < numFiles; i++) { CSzFileItem *f = &files[i]; uint8_t defined = (*lwtVector)[i]; f->MTimeDefined = defined; f->MTime.Low = f->MTime.High = 0; if (defined) { RINOK(SzReaduint32_t(sd, &f->MTime.Low)); RINOK(SzReaduint32_t(sd, &f->MTime.High)); } } IAlloc_Free(allocTemp, *lwtVector); *lwtVector = NULL; break; } default: { RINOK(SzSkeepDataSize(sd, size)); } } } { uint32_t emptyFileIndex = 0; uint32_t sizeIndex = 0; for (i = 0; i < numFiles; i++) { CSzFileItem *file = files + i; file->IsAnti = 0; if (*emptyStreamVector == 0) file->HasStream = 1; else file->HasStream = (uint8_t)((*emptyStreamVector)[i] ? 0 : 1); if (file->HasStream) { file->IsDir = 0; file->Size = (*unpackSizes)[sizeIndex]; file->Crc = (*digests)[sizeIndex]; file->CrcDefined = (uint8_t)(*digestsDefined)[sizeIndex]; sizeIndex++; } else { if (*emptyFileVector == 0) file->IsDir = 1; else file->IsDir = (uint8_t)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); emptyFileIndex++; file->Size = 0; file->Crc = 0; file->CrcDefined = 0; } } } return SzArEx_Fill(p, allocMain); }