diff -r ea891871f481 -r bb5522e88ab2 misc/libphysfs/lzma/C/Archive/7z/7zExtract.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/libphysfs/lzma/C/Archive/7z/7zExtract.c Mon Apr 10 12:06:43 2017 -0400 @@ -0,0 +1,119 @@ +/* 7zExtract.c */ + +#include "7zExtract.h" +#include "7zDecode.h" +#include "../../7zCrc.h" + +SZ_RESULT SzExtract( + ISzInStream *inStream, + CArchiveDatabaseEx *db, + UInt32 fileIndex, + UInt32 *blockIndex, + Byte **outBuffer, + size_t *outBufferSize, + size_t *offset, + size_t *outSizeProcessed, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex]; + SZ_RESULT res = SZ_OK; + *offset = 0; + *outSizeProcessed = 0; + if (folderIndex == (UInt32)-1) + { + allocMain->Free(*outBuffer); + *blockIndex = folderIndex; + *outBuffer = 0; + *outBufferSize = 0; + return SZ_OK; + } + + if (*outBuffer == 0 || *blockIndex != folderIndex) + { + CFolder *folder = db->Database.Folders + folderIndex; + CFileSize unPackSizeSpec = SzFolderGetUnPackSize(folder); + size_t unPackSize = (size_t)unPackSizeSpec; + CFileSize startOffset = SzArDbGetFolderStreamPos(db, folderIndex, 0); + #ifndef _LZMA_IN_CB + Byte *inBuffer = 0; + size_t processedSize; + CFileSize packSizeSpec; + size_t packSize; + RINOK(SzArDbGetFolderFullPackSize(db, folderIndex, &packSizeSpec)); + packSize = (size_t)packSizeSpec; + if (packSize != packSizeSpec) + return SZE_OUTOFMEMORY; + #endif + if (unPackSize != unPackSizeSpec) + return SZE_OUTOFMEMORY; + *blockIndex = folderIndex; + allocMain->Free(*outBuffer); + *outBuffer = 0; + + RINOK(inStream->Seek(inStream, startOffset)); + + #ifndef _LZMA_IN_CB + if (packSize != 0) + { + inBuffer = (Byte *)allocTemp->Alloc(packSize); + if (inBuffer == 0) + return SZE_OUTOFMEMORY; + } + res = inStream->Read(inStream, inBuffer, packSize, &processedSize); + if (res == SZ_OK && processedSize != packSize) + res = SZE_FAIL; + #endif + if (res == SZ_OK) + { + *outBufferSize = unPackSize; + if (unPackSize != 0) + { + *outBuffer = (Byte *)allocMain->Alloc(unPackSize); + if (*outBuffer == 0) + res = SZE_OUTOFMEMORY; + } + if (res == SZ_OK) + { + res = SzDecode(db->Database.PackSizes + + db->FolderStartPackStreamIndex[folderIndex], folder, + #ifdef _LZMA_IN_CB + inStream, startOffset, + #else + inBuffer, + #endif + *outBuffer, unPackSize, allocTemp); + if (res == SZ_OK) + { + if (folder->UnPackCRCDefined) + { + if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC) + res = SZE_CRC_ERROR; + } + } + } + } + #ifndef _LZMA_IN_CB + allocTemp->Free(inBuffer); + #endif + } + if (res == SZ_OK) + { + UInt32 i; + CFileItem *fileItem = db->Database.Files + fileIndex; + *offset = 0; + for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) + *offset += (UInt32)db->Database.Files[i].Size; + *outSizeProcessed = (size_t)fileItem->Size; + if (*offset + *outSizeProcessed > *outBufferSize) + return SZE_FAIL; + { + if (fileItem->IsFileCRCDefined) + { + if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC) + res = SZE_CRC_ERROR; + } + } + } + return res; +}