(deps/7zip) Cleanups

This commit is contained in:
twinaphex 2020-07-01 16:50:54 +02:00
parent 14e20cea51
commit 867daa7efb
6 changed files with 1510 additions and 1106 deletions

557
deps/7zip/7zDec.c vendored
View File

@ -23,44 +23,60 @@
#define k_SPARC 0x03030805 #define k_SPARC 0x03030805
#define k_BCJ2 0x0303011B #define k_BCJ2 0x0303011B
static SRes SzDecodeLzma(CSzCoderInfo *coder, uint64_t inSize, ILookInStream *inStream, static SRes SzDecodeLzma(CSzCoderInfo *coder,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain) uint64_t inSize, ILookInStream *inStream,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain)
{ {
int result;
CLzmaDec state; CLzmaDec state;
SRes res = SZ_OK; SRes res = SZ_OK;
LzmaDec_Construct(&state); LzmaDec_Construct(&state);
RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); result = LzmaDec_AllocateProbs(
state.dic = outBuffer; &state, coder->Props.data,
(unsigned)coder->Props.size, allocMain);
if (result != 0)
return result;
state.dic = outBuffer;
state.dicBufSize = outSize; state.dicBufSize = outSize;
LzmaDec_Init(&state); LzmaDec_Init(&state);
for (;;) for (;;)
{ {
uint8_t *inBuf = NULL; uint8_t *inBuf = NULL;
size_t lookahead = (1 << 18); size_t lookahead = (1 << 18);
if (lookahead > inSize) if (lookahead > inSize)
lookahead = (size_t)inSize; lookahead = (size_t)inSize;
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); res = inStream->Look(
(void *)inStream, (const void **)&inBuf, &lookahead);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
{ {
size_t inProcessed = (size_t)lookahead, dicPos = state.dicPos;
ELzmaStatus status; ELzmaStatus status;
res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); size_t inProcessed = (size_t)lookahead, dicPos = state.dicPos;
lookahead -= inProcessed; res = LzmaDec_DecodeToDic(
inSize -= inProcessed; &state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
lookahead -= inProcessed;
inSize -= inProcessed;
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
if (
state.dicPos == state.dicBufSize ||
(inProcessed == 0 && dicPos == state.dicPos))
{ {
if (state.dicBufSize != outSize || lookahead != 0 || if (
state.dicBufSize != outSize ||
lookahead != 0 ||
(status != LZMA_STATUS_FINISHED_WITH_MARK && (status != LZMA_STATUS_FINISHED_WITH_MARK &&
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
break; break;
} }
res = inStream->Skip((void *)inStream, inProcessed); res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@ -71,153 +87,185 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, uint64_t inSize, ILookInStream *in
return res; return res;
} }
static SRes SzDecodeLzma2(CSzCoderInfo *coder, uint64_t inSize, ILookInStream *inStream, static SRes SzDecodeLzma2(CSzCoderInfo *coder,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain) uint64_t inSize, ILookInStream *inStream,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain)
{ {
CLzma2Dec state; int result;
SRes res = SZ_OK; CLzma2Dec state;
SRes res = SZ_OK;
Lzma2Dec_Construct(&state); Lzma2Dec_Construct(&state);
if (coder->Props.size != 1) if (coder->Props.size != 1)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
state.decoder.dic = outBuffer;
state.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&state);
for (;;) result = Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain);
{ if (result != 0)
uint8_t *inBuf = NULL; return result;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
if (res != SZ_OK)
break;
{ state.decoder.dic = outBuffer;
size_t inProcessed = (size_t)lookahead, dicPos = state.decoder.dicPos; state.decoder.dicBufSize = outSize;
ELzmaStatus status; Lzma2Dec_Init(&state);
res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
lookahead -= inProcessed; for (;;)
inSize -= inProcessed; {
uint8_t *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
res = inStream->Look(
(void *)inStream, (const void **)&inBuf, &lookahead);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
{ {
if (state.decoder.dicBufSize != outSize || lookahead != 0 || ELzmaStatus status;
(status != LZMA_STATUS_FINISHED_WITH_MARK)) size_t inProcessed = (size_t)lookahead, dicPos = state.decoder.dicPos;
res = SZ_ERROR_DATA; res = Lzma2Dec_DecodeToDic(
break; &state, outSize, inBuf, &inProcessed,
LZMA_FINISH_END, &status);
lookahead -= inProcessed;
inSize -= inProcessed;
if (res != SZ_OK)
break;
if (
state.decoder.dicPos == state.decoder.dicBufSize ||
(inProcessed == 0 && dicPos == state.decoder.dicPos))
{
if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
(status != LZMA_STATUS_FINISHED_WITH_MARK))
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK)
break;
} }
res = inStream->Skip((void *)inStream, inProcessed); }
if (res != SZ_OK)
break;
}
}
Lzma2Dec_FreeProbs(&state, allocMain); Lzma2Dec_FreeProbs(&state, allocMain);
return res; return res;
} }
static SRes SzDecodeCopy(uint64_t inSize, ILookInStream *inStream, uint8_t *outBuffer) static SRes SzDecodeCopy(uint64_t inSize,
ILookInStream *inStream, uint8_t *outBuffer)
{ {
while (inSize > 0) while (inSize > 0)
{ {
void *inBuf; int result;
size_t curSize = (1 << 18); void *inBuf = NULL;
if (curSize > inSize) size_t curSize = (1 << 18);
curSize = (size_t)inSize; if (curSize > inSize)
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); curSize = (size_t)inSize;
if (curSize == 0) result = inStream->Look(
return SZ_ERROR_INPUT_EOF; (void *)inStream, (const void **)&inBuf, &curSize);
memcpy(outBuffer, inBuf, curSize);
outBuffer += curSize; if (result != 0)
inSize -= curSize; return result;
RINOK(inStream->Skip((void *)inStream, curSize)); if (curSize == 0)
} return SZ_ERROR_INPUT_EOF;
return SZ_OK;
memcpy(outBuffer, inBuf, curSize);
outBuffer += curSize;
inSize -= curSize;
result = inStream->Skip((void *)inStream, curSize);
if (result != 0)
return result;
}
return SZ_OK;
} }
static bool IS_MAIN_METHOD(uint32_t m) static bool is_main_method(uint32_t m)
{ {
switch(m) switch(m)
{ {
case k_Copy: case k_Copy:
case k_LZMA: case k_LZMA:
case k_LZMA2: case k_LZMA2:
return true; return true;
} default:
return false; break;
}
return false;
} }
static bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) static bool is_supported_coder(const CSzCoderInfo *c)
{ {
return return
c->NumInStreams == 1 && c->NumInStreams == 1 &&
c->NumOutStreams == 1 && c->NumOutStreams == 1 &&
c->MethodID <= (uint32_t)0xFFFFFFFF && c->MethodID <= (uint32_t)0xFFFFFFFF &&
IS_MAIN_METHOD((uint32_t)c->MethodID); is_main_method((uint32_t)c->MethodID);
} }
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1) #define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
static SRes CheckSupportedFolder(const CSzFolder *f) static SRes check_supported_folder(const CSzFolder *f)
{ {
if (f->NumCoders < 1 || f->NumCoders > 4) if (f->NumCoders < 1 || f->NumCoders > 4)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
if (!is_supported_coder(&f->Coders[0]))
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
if (f->NumCoders == 1)
switch (f->NumCoders)
{ {
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) case 1:
return SZ_ERROR_UNSUPPORTED; if ( f->NumPackStreams != 1
return SZ_OK; || f->PackStreams[0] != 0
} || f->NumBindPairs != 0)
if (f->NumCoders == 2) return SZ_ERROR_UNSUPPORTED;
{ return SZ_OK;
CSzCoderInfo *c = &f->Coders[1]; case 2:
if (c->MethodID > (uint32_t)0xFFFFFFFF || {
c->NumInStreams != 1 || CSzCoderInfo *c = &f->Coders[1];
c->NumOutStreams != 1 ||
f->NumPackStreams != 1 || if (c->MethodID > (uint32_t)0xFFFFFFFF ||
f->PackStreams[0] != 0 || c->NumInStreams != 1 ||
f->NumBindPairs != 1 || c->NumOutStreams != 1 ||
f->BindPairs[0].InIndex != 1 || f->NumPackStreams != 1 ||
f->BindPairs[0].OutIndex != 0) f->PackStreams[0] != 0 ||
return SZ_ERROR_UNSUPPORTED; f->NumBindPairs != 1 ||
switch ((uint32_t)c->MethodID) f->BindPairs[0].InIndex != 1 ||
{ f->BindPairs[0].OutIndex != 0)
case k_BCJ: return SZ_ERROR_UNSUPPORTED;
case k_ARM:
break; switch ((uint32_t)c->MethodID)
default: {
return SZ_ERROR_UNSUPPORTED; case k_BCJ:
} case k_ARM:
return SZ_OK; break;
} default:
if (f->NumCoders == 4) return SZ_ERROR_UNSUPPORTED;
{ }
if (!IS_SUPPORTED_CODER(&f->Coders[1]) || }
!IS_SUPPORTED_CODER(&f->Coders[2]) || return SZ_OK;
!IS_BCJ2(&f->Coders[3])) case 4:
return SZ_ERROR_UNSUPPORTED; if (!is_supported_coder(&f->Coders[1]) ||
if (f->NumPackStreams != 4 || !is_supported_coder(&f->Coders[2]) ||
f->PackStreams[0] != 2 || !IS_BCJ2(&f->Coders[3]))
f->PackStreams[1] != 6 || return SZ_ERROR_UNSUPPORTED;
f->PackStreams[2] != 1 ||
f->PackStreams[3] != 0 || if (f->NumPackStreams != 4 ||
f->NumBindPairs != 3 || f->PackStreams[0] != 2 ||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || f->PackStreams[1] != 6 ||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || f->PackStreams[2] != 1 ||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) f->PackStreams[3] != 0 ||
return SZ_ERROR_UNSUPPORTED; f->NumBindPairs != 3 ||
return SZ_OK; f->BindPairs[0].InIndex != 5 ||
f->BindPairs[0].OutIndex != 0 ||
f->BindPairs[1].InIndex != 4 ||
f->BindPairs[1].OutIndex != 1 ||
f->BindPairs[2].InIndex != 3 ||
f->BindPairs[2].OutIndex != 2)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
} }
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
} }
static uint64_t GetSum(const uint64_t *values, uint32_t idx) static uint64_t get_sum(const uint64_t *values, uint32_t idx)
{ {
uint64_t sum = 0; uint64_t sum = 0;
uint32_t i; uint32_t i;
@ -226,134 +274,169 @@ static uint64_t GetSum(const uint64_t *values, uint32_t idx)
return sum; return sum;
} }
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; static SRes SzFolder_Decode2(const CSzFolder *folder,
const uint64_t *packSizes,
static SRes SzFolder_Decode2(const CSzFolder *folder, const uint64_t *packSizes, ILookInStream *inStream, uint64_t startPos,
ILookInStream *inStream, uint64_t startPos, uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain, uint8_t *tempBuf[])
uint8_t *tempBuf[])
{ {
uint32_t ci; uint32_t ci;
size_t tempSizes[3] = { 0, 0, 0}; size_t tempSizes[3] = { 0, 0, 0};
size_t tempSize3 = 0; size_t tempSize3 = 0;
uint8_t *tempBuf3 = 0; uint8_t *tempBuf3 = 0;
int result = check_supported_folder(folder);
RINOK(CheckSupportedFolder(folder)); if (result != 0)
return result;
for (ci = 0; ci < folder->NumCoders; ci++) for (ci = 0; ci < folder->NumCoders; ci++)
{ {
CSzCoderInfo *coder = &folder->Coders[ci]; CSzCoderInfo *coder = &folder->Coders[ci];
if (IS_MAIN_METHOD((uint32_t)coder->MethodID)) if (is_main_method((uint32_t)coder->MethodID))
{
uint32_t si = 0;
uint64_t offset;
uint64_t inSize;
uint8_t *outBufCur = outBuffer;
size_t outSizeCur = outSize;
if (folder->NumCoders == 4)
{ {
uint32_t indices[] = { 3, 2, 0 }; int result;
uint64_t unpackSize = folder->UnpackSizes[ci]; uint64_t offset = 0;
si = indices[ci]; uint64_t inSize = 0;
if (ci < 2) uint32_t si = 0;
{ uint8_t *outBufCur = outBuffer;
uint8_t *temp; size_t outSizeCur = outSize;
outSizeCur = (size_t)unpackSize;
if (outSizeCur != unpackSize) if (folder->NumCoders == 4)
{
uint32_t indices[] = { 3, 2, 0 };
uint64_t unpackSize = folder->UnpackSizes[ci];
si = indices[ci];
if (ci < 2)
{
uint8_t *temp;
outSizeCur = (size_t)unpackSize;
if (outSizeCur != unpackSize)
return SZ_ERROR_MEM;
temp = (uint8_t *)IAlloc_Alloc(allocMain, outSizeCur);
if (temp == 0 && outSizeCur != 0)
return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur;
}
else if (ci == 2)
{
if (unpackSize > outSize) /* check it */
return SZ_ERROR_PARAM;
tempBuf3 = outBufCur = outBuffer
+ (outSize - (size_t)unpackSize);
tempSize3 = outSizeCur = (size_t)unpackSize;
}
else
return SZ_ERROR_UNSUPPORTED;
}
offset = get_sum(packSizes, si);
inSize = packSizes[si];
result = LookInStream_SeekTo(inStream, startPos + offset);
if (result != 0)
return result;
switch (coder->MethodID)
{
case k_Copy:
if (inSize != outSizeCur) /* check it */
return SZ_ERROR_DATA;
result = SzDecodeCopy(inSize, inStream, outBufCur);
if (result != 0)
return result;
break;
case k_LZMA:
result = SzDecodeLzma(
coder, inSize, inStream,
outBufCur, outSizeCur, allocMain);
if (result != 0)
return result;
break;
case k_LZMA2:
result = SzDecodeLzma2(
coder, inSize, inStream,
outBufCur, outSizeCur, allocMain);
if (result != 0)
return result;
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
}
else if (coder->MethodID == k_BCJ2)
{
SRes res;
int result;
uint64_t offset = get_sum(packSizes, 1);
uint64_t s3Size = packSizes[1];
if (ci != 3)
return SZ_ERROR_UNSUPPORTED;
result = LookInStream_SeekTo(inStream, startPos + offset);
if (result != 0)
return result;
tempSizes[2] = (size_t)s3Size;
if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
temp = (uint8_t *)IAlloc_Alloc(allocMain, outSizeCur);
if (temp == 0 && outSizeCur != 0)
return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur;
}
else if (ci == 2)
{
if (unpackSize > outSize) /* check it */
return SZ_ERROR_PARAM;
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
tempSize3 = outSizeCur = (size_t)unpackSize;
}
else
return SZ_ERROR_UNSUPPORTED;
}
offset = GetSum(packSizes, si);
inSize = packSizes[si];
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
if (coder->MethodID == k_Copy) tempBuf[2] = (uint8_t *)IAlloc_Alloc(allocMain, tempSizes[2]);
{ if (tempBuf[2] == 0 && tempSizes[2] != 0)
if (inSize != outSizeCur) /* check it */ return SZ_ERROR_MEM;
return SZ_ERROR_DATA;
RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
} if (res != 0)
else if (coder->MethodID == k_LZMA) return res;
{
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); res = Bcj2_Decode(
} tempBuf3, tempSize3,
else if (coder->MethodID == k_LZMA2) tempBuf[0], tempSizes[0],
{ tempBuf[1], tempSizes[1],
RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); tempBuf[2], tempSizes[2],
outBuffer, outSize);
if (res != 0)
return res;
} }
else else
return SZ_ERROR_UNSUPPORTED;
}
else if (coder->MethodID == k_BCJ2)
{
uint64_t offset = GetSum(packSizes, 1);
uint64_t s3Size = packSizes[1];
SRes res;
if (ci != 3)
return SZ_ERROR_UNSUPPORTED;
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
tempSizes[2] = (size_t)s3Size;
if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM;
tempBuf[2] = (uint8_t *)IAlloc_Alloc(allocMain, tempSizes[2]);
if (tempBuf[2] == 0 && tempSizes[2] != 0)
return SZ_ERROR_MEM;
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
RINOK(res)
res = Bcj2_Decode(
tempBuf3, tempSize3,
tempBuf[0], tempSizes[0],
tempBuf[1], tempSizes[1],
tempBuf[2], tempSizes[2],
outBuffer, outSize);
RINOK(res)
}
else
{
if (ci != 1)
return SZ_ERROR_UNSUPPORTED;
switch(coder->MethodID)
{ {
case k_BCJ: if (ci != 1)
{ return SZ_ERROR_UNSUPPORTED;
uint32_t state; switch(coder->MethodID)
x86_Convert_Init(state); {
x86_Convert(outBuffer, outSize, 0, &state, 0); case k_BCJ:
break; {
} uint32_t state;
CASE_BRA_CONV(ARM) x86_Convert_Init(state);
default: x86_Convert(outBuffer, outSize, 0, &state, 0);
return SZ_ERROR_UNSUPPORTED; break;
}
case k_ARM:
ARM_Convert(outBuffer, outSize, 0, 0);
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
} }
} }
} return SZ_OK;
return SZ_OK;
} }
SRes SzFolder_Decode(const CSzFolder *folder, const uint64_t *packSizes, SRes SzFolder_Decode(const CSzFolder *folder, const uint64_t *packSizes,
ILookInStream *inStream, uint64_t startPos, ILookInStream *inStream, uint64_t startPos,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain) uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain)
{ {
uint8_t *tempBuf[3] = { 0, 0, 0};
int i; int i;
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos, uint8_t *tempBuf[3] = { 0, 0, 0};
outBuffer, (size_t)outSize, allocMain, tempBuf); SRes res = SzFolder_Decode2(folder,
packSizes, inStream, startPos,
outBuffer, (size_t)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]); IAlloc_Free(allocMain, tempBuf[i]);
return res; return res;

441
deps/7zip/7zIn.c vendored
View File

@ -10,8 +10,6 @@
uint8_t k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; uint8_t k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
#define NUM_FOLDER_CODERS_MAX 32 #define NUM_FOLDER_CODERS_MAX 32
#define NUM_CODER_STREAMS_MAX 32 #define NUM_CODER_STREAMS_MAX 32
@ -320,7 +318,9 @@ static SRes SzReaduint8_ts(CSzData *sd, uint8_t *data, size_t size)
size_t i; size_t i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
RINOK(SzReaduint8_t(sd, data + i)); int result = SzReaduint8_t(sd, data + i);
if (result != 0)
return result;
} }
return SZ_OK; return SZ_OK;
} }
@ -331,8 +331,10 @@ static SRes SzReaduint32_t(CSzData *sd, uint32_t *value)
*value = 0; *value = 0;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
uint8_t b = 0; uint8_t b = 0;
RINOK(SzReaduint8_t(sd, &b)); int result = SzReaduint8_t(sd, &b);
if (result != 0)
return result;
*value |= ((uint32_t)(b) << (8 * i)); *value |= ((uint32_t)(b) << (8 * i));
} }
return SZ_OK; return SZ_OK;
@ -343,13 +345,16 @@ static SRes SzReadNumber(CSzData *sd, uint64_t *value)
int i; int i;
uint8_t firstuint8_t = 0; uint8_t firstuint8_t = 0;
uint8_t mask = 0x80; uint8_t mask = 0x80;
int result = SzReaduint8_t(sd, &firstuint8_t);
RINOK(SzReaduint8_t(sd, &firstuint8_t)); if (result != 0)
return result;
*value = 0; *value = 0;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
int result;
uint8_t b = 0; uint8_t b = 0;
if ((firstuint8_t & mask) == 0) if ((firstuint8_t & mask) == 0)
{ {
@ -357,7 +362,10 @@ static SRes SzReadNumber(CSzData *sd, uint64_t *value)
*value += (highPart << (8 * i)); *value += (highPart << (8 * i));
return SZ_OK; return SZ_OK;
} }
RINOK(SzReaduint8_t(sd, &b)); result = SzReaduint8_t(sd, &b);
if (result != 0)
return result;
*value |= ((uint64_t)b << (8 * i)); *value |= ((uint64_t)b << (8 * i));
mask >>= 1; mask >>= 1;
} }
@ -367,7 +375,9 @@ static SRes SzReadNumber(CSzData *sd, uint64_t *value)
static SRes SzReadNumber32(CSzData *sd, uint32_t *value) static SRes SzReadNumber32(CSzData *sd, uint32_t *value)
{ {
uint64_t value64; uint64_t value64;
RINOK(SzReadNumber(sd, &value64)); int result = SzReadNumber(sd, &value64);
if (result != 0)
return result;
if (value64 >= 0x80000000) if (value64 >= 0x80000000)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
if (value64 >= ((uint64_t)(1) << ((sizeof(size_t) - 1) * 8 + 2))) if (value64 >= ((uint64_t)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
@ -393,7 +403,9 @@ static SRes SzSkeepDataSize(CSzData *sd, uint64_t size)
static SRes SzSkeepData(CSzData *sd) static SRes SzSkeepData(CSzData *sd)
{ {
uint64_t size; uint64_t size;
RINOK(SzReadNumber(sd, &size)); int result = SzReadNumber(sd, &size);
if (result != 0)
return result;
return SzSkeepDataSize(sd, size); return SzSkeepDataSize(sd, size);
} }
@ -402,7 +414,9 @@ static SRes SzReadArchiveProperties(CSzData *sd)
for (;;) for (;;)
{ {
uint64_t type; uint64_t type;
RINOK(SzReadID(sd, &type)); int result = SzReadID(sd, &type);
if (result != 0)
return result;
if (type == k7zIdEnd) if (type == k7zIdEnd)
break; break;
SzSkeepData(sd); SzSkeepData(sd);
@ -415,12 +429,16 @@ static SRes SzWaitAttribute(CSzData *sd, uint64_t attribute)
for (;;) for (;;)
{ {
uint64_t type; uint64_t type;
RINOK(SzReadID(sd, &type)); int result = SzReadID(sd, &type);
if (result != 0)
return result;
if (type == attribute) if (type == attribute)
return SZ_OK; return SZ_OK;
if (type == k7zIdEnd) if (type == k7zIdEnd)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
RINOK(SzSkeepData(sd)); result = SzSkeepData(sd);
if (result != 0)
return result;
} }
} }
@ -435,8 +453,10 @@ static SRes SzReadBoolVector(
{ {
if (mask == 0) if (mask == 0)
{ {
RINOK(SzReaduint8_t(sd, &b)); int result = SzReaduint8_t(sd, &b);
mask = 0x80; if (result != 0)
return result;
mask = 0x80;
} }
(*v)[i] = (uint8_t)(((b & mask) != 0) ? 1 : 0); (*v)[i] = (uint8_t)(((b & mask) != 0) ? 1 : 0);
mask >>= 1; mask >>= 1;
@ -448,7 +468,10 @@ static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, uint8_t **v, ISzAllo
{ {
size_t i; size_t i;
uint8_t allAreDefined = 0; uint8_t allAreDefined = 0;
RINOK(SzReaduint8_t(sd, &allAreDefined)); int result = SzReaduint8_t(sd, &allAreDefined);
if (result != 0)
return result;
if (allAreDefined == 0) if (allAreDefined == 0)
return SzReadBoolVector(sd, numItems, v, alloc); return SzReadBoolVector(sd, numItems, v, alloc);
MY_ALLOC(uint8_t, *v, numItems, alloc); MY_ALLOC(uint8_t, *v, numItems, alloc);
@ -465,13 +488,22 @@ static SRes SzReadHashDigests(
ISzAlloc *alloc) ISzAlloc *alloc)
{ {
size_t i; size_t i;
RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); int result = SzReadBoolVector2(sd, numItems, digestsDefined, alloc);
if (result != 0)
return result;
MY_ALLOC(uint32_t, *digests, numItems, alloc); MY_ALLOC(uint32_t, *digests, numItems, alloc);
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
{
if ((*digestsDefined)[i]) if ((*digestsDefined)[i])
{ {
RINOK(SzReaduint32_t(sd, (*digests) + i)); int result = SzReaduint32_t(sd, (*digests) + i);
if (result != 0)
return result;
} }
}
return SZ_OK; return SZ_OK;
} }
@ -485,30 +517,44 @@ static SRes SzReadPackInfo(
ISzAlloc *alloc) ISzAlloc *alloc)
{ {
uint32_t i; uint32_t i;
RINOK(SzReadNumber(sd, dataOffset)); int result = SzReadNumber(sd, dataOffset);
RINOK(SzReadNumber32(sd, numPackStreams));
RINOK(SzWaitAttribute(sd, k7zIdSize)); if (result != 0)
return result;
result = SzReadNumber32(sd, numPackStreams);
if (result != 0)
return result;
result = SzWaitAttribute(sd, k7zIdSize);
if (result != 0)
return result;
MY_ALLOC(uint64_t, *packSizes, (size_t)*numPackStreams, alloc); MY_ALLOC(uint64_t, *packSizes, (size_t)*numPackStreams, alloc);
for (i = 0; i < *numPackStreams; i++) for (i = 0; i < *numPackStreams; i++)
{ {
RINOK(SzReadNumber(sd, (*packSizes) + i)); result = SzReadNumber(sd, (*packSizes) + i);
if (result != 0)
return result;
} }
for (;;) for (;;)
{ {
uint64_t type; uint64_t type;
RINOK(SzReadID(sd, &type)); result = SzReadID(sd, &type);
if (result != 0)
return result;
if (type == k7zIdEnd) if (type == k7zIdEnd)
break; break;
if (type == k7zIdCRC) if (type == k7zIdCRC)
{ {
RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); result = SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc);
if (result != 0)
return result;
continue; continue;
} }
RINOK(SzSkeepData(sd)); result = SzSkeepData(sd);
if (result != 0)
return result;
} }
if (*packCRCsDefined == 0) if (*packCRCsDefined == 0)
{ {
@ -526,8 +572,12 @@ static SRes SzReadPackInfo(
static SRes SzReadSwitch(CSzData *sd) static SRes SzReadSwitch(CSzData *sd)
{ {
uint8_t external = 0; uint8_t external = 0;
RINOK(SzReaduint8_t(sd, &external)); int result = SzReaduint8_t(sd, &external);
return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; if (result != 0)
return result;
if (external != 0)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
} }
static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
@ -538,8 +588,10 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
uint32_t numInStreams = 0; uint32_t numInStreams = 0;
uint32_t numOutStreams = 0; uint32_t numOutStreams = 0;
uint32_t numCoders = 0; uint32_t numCoders = 0;
int result = SzReadNumber32(sd, &numCoders);
RINOK(SzReadNumber32(sd, &numCoders)); if (result != 0)
return result;
if (numCoders > NUM_FOLDER_CODERS_MAX) if (numCoders > NUM_FOLDER_CODERS_MAX)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
folder->NumCoders = numCoders; folder->NumCoders = numCoders;
@ -555,19 +607,36 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
uint8_t longID[15]; uint8_t longID[15];
uint8_t mainuint8_t = 0; uint8_t mainuint8_t = 0;
CSzCoderInfo *coder = folder->Coders + i; CSzCoderInfo *coder = folder->Coders + i;
RINOK(SzReaduint8_t(sd, &mainuint8_t)); int result = SzReaduint8_t(sd, &mainuint8_t);
idSize = (unsigned)(mainuint8_t & 0xF);
RINOK(SzReaduint8_ts(sd, longID, idSize)); if (result != 0)
return result;
idSize = (unsigned)(mainuint8_t & 0xF);
result = SzReaduint8_ts(sd, longID, idSize);
if (result != 0)
return result;
if (idSize > sizeof(coder->MethodID)) if (idSize > sizeof(coder->MethodID))
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
coder->MethodID = 0;
coder->MethodID = 0;
for (j = 0; j < idSize; j++) for (j = 0; j < idSize; j++)
coder->MethodID |= (uint64_t)longID[idSize - 1 - j] << (8 * j); coder->MethodID |= (uint64_t)longID[idSize - 1 - j] << (8 * j);
if ((mainuint8_t & 0x10) != 0) if ((mainuint8_t & 0x10) != 0)
{ {
RINOK(SzReadNumber32(sd, &coder->NumInStreams)); int result = SzReadNumber32(sd, &coder->NumInStreams);
RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
if (result != 0)
return result;
result = SzReadNumber32(sd, &coder->NumOutStreams);
if (result != 0)
return result;
if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||
coder->NumOutStreams > NUM_CODER_STREAMS_MAX) coder->NumOutStreams > NUM_CODER_STREAMS_MAX)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
@ -580,26 +649,43 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
if ((mainuint8_t & 0x20) != 0) if ((mainuint8_t & 0x20) != 0)
{ {
uint64_t propertiesSize = 0; uint64_t propertiesSize = 0;
RINOK(SzReadNumber(sd, &propertiesSize)); int result = SzReadNumber(sd, &propertiesSize);
if (result != 0)
return result;
if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
RINOK(SzReaduint8_ts(sd, coder->Props.data, (size_t)propertiesSize)); result = SzReaduint8_ts(sd, coder->Props.data, (size_t)propertiesSize);
if (result != 0)
return result;
} }
while ((mainuint8_t & 0x80) != 0) while ((mainuint8_t & 0x80) != 0)
{ {
RINOK(SzReaduint8_t(sd, &mainuint8_t)); result = SzReaduint8_t(sd, &mainuint8_t);
RINOK(SzSkeepDataSize(sd, (mainuint8_t & 0xF))); if (result != 0)
return result;
result = SzSkeepDataSize(sd, (mainuint8_t & 0xF));
if (result != 0)
return result;
if ((mainuint8_t & 0x10) != 0) if ((mainuint8_t & 0x10) != 0)
{ {
uint32_t n; uint32_t n;
RINOK(SzReadNumber32(sd, &n)); int result = SzReadNumber32(sd, &n);
RINOK(SzReadNumber32(sd, &n)); if (result != 0)
return result;
result = SzReadNumber32(sd, &n);
if (result != 0)
return result;
} }
if ((mainuint8_t & 0x20) != 0) if ((mainuint8_t & 0x20) != 0)
{ {
uint64_t propertiesSize = 0; uint64_t propertiesSize = 0;
RINOK(SzReadNumber(sd, &propertiesSize)); int result = SzReadNumber(sd, &propertiesSize);
RINOK(SzSkeepDataSize(sd, propertiesSize)); if (result != 0)
return result;
result = SzSkeepDataSize(sd, propertiesSize);
if (result != 0)
return result;
} }
} }
numInStreams += coder->NumInStreams; numInStreams += coder->NumInStreams;
@ -615,8 +701,13 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
for (i = 0; i < numBindPairs; i++) for (i = 0; i < numBindPairs; i++)
{ {
CSzBindPair *bp = folder->BindPairs + i; CSzBindPair *bp = folder->BindPairs + i;
RINOK(SzReadNumber32(sd, &bp->InIndex)); int result = SzReadNumber32(sd, &bp->InIndex);
RINOK(SzReadNumber32(sd, &bp->OutIndex));
if (result != 0)
return result;
result = SzReadNumber32(sd, &bp->OutIndex);
if (result != 0)
return result;
} }
if (numInStreams < numBindPairs) if (numInStreams < numBindPairs)
@ -637,7 +728,9 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
else else
for (i = 0; i < numPackStreams; i++) for (i = 0; i < numPackStreams; i++)
{ {
RINOK(SzReadNumber32(sd, folder->PackStreams + i)); int result = SzReadNumber32(sd, folder->PackStreams + i);
if (result != 0)
return result;
} }
return SZ_OK; return SZ_OK;
} }
@ -650,10 +743,21 @@ static SRes SzReadUnpackInfo(
ISzAlloc *allocTemp) ISzAlloc *allocTemp)
{ {
uint32_t i; uint32_t i;
RINOK(SzWaitAttribute(sd, k7zIdFolder)); int result = SzWaitAttribute(sd, k7zIdFolder);
RINOK(SzReadNumber32(sd, numFolders));
if (result != 0)
return result;
result = SzReadNumber32(sd, numFolders);
if (result != 0)
return result;
{ {
RINOK(SzReadSwitch(sd)); result = SzReadSwitch(sd);
if (result != 0)
return result;
MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);
@ -662,11 +766,17 @@ static SRes SzReadUnpackInfo(
for (i = 0; i < *numFolders; i++) for (i = 0; i < *numFolders; i++)
{ {
RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); result = SzGetNextFolderItem(sd, (*folders) + i, alloc);
if (result != 0)
return result;
} }
} }
RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); result = SzWaitAttribute(sd, k7zIdCodersUnpackSize);
if (result != 0)
return result;
for (i = 0; i < *numFolders; i++) for (i = 0; i < *numFolders; i++)
{ {
@ -678,22 +788,27 @@ static SRes SzReadUnpackInfo(
for (j = 0; j < numOutStreams; j++) for (j = 0; j < numOutStreams; j++)
{ {
RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); int result = SzReadNumber(sd, folder->UnpackSizes + j);
if (result != 0)
return result;
} }
} }
for (;;) for (;;)
{ {
uint64_t type; uint64_t type;
RINOK(SzReadID(sd, &type)); int result = SzReadID(sd, &type);
if (result != 0)
return result;
if (type == k7zIdEnd) if (type == k7zIdEnd)
return SZ_OK; return SZ_OK;
if (type == k7zIdCRC) if (type == k7zIdCRC)
{ {
SRes res;
uint8_t *crcsDefined = 0; uint8_t *crcsDefined = 0;
uint32_t *crcs = 0; uint32_t *crcs = 0;
res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); SRes res = SzReadHashDigests(
sd, *numFolders, &crcsDefined, &crcs, allocTemp);
if (res == SZ_OK) if (res == SZ_OK)
{ {
for (i = 0; i < *numFolders; i++) for (i = 0; i < *numFolders; i++)
@ -705,10 +820,13 @@ static SRes SzReadUnpackInfo(
} }
IAlloc_Free(allocTemp, crcs); IAlloc_Free(allocTemp, crcs);
IAlloc_Free(allocTemp, crcsDefined); IAlloc_Free(allocTemp, crcsDefined);
RINOK(res); if (res != 0)
return res;
continue; continue;
} }
RINOK(SzSkeepData(sd)); result = SzSkeepData(sd);
if (result != 0)
return result;
} }
} }
@ -722,6 +840,7 @@ static SRes SzReadSubStreamsInfo(
uint32_t **digests, uint32_t **digests,
ISzAlloc *allocTemp) ISzAlloc *allocTemp)
{ {
int result;
uint32_t i; uint32_t i;
uint64_t type = 0; uint64_t type = 0;
uint32_t si = 0; uint32_t si = 0;
@ -733,14 +852,19 @@ static SRes SzReadSubStreamsInfo(
for (;;) for (;;)
{ {
RINOK(SzReadID(sd, &type)); int result = SzReadID(sd, &type);
if (result != 0)
return result;
if (type == k7zIdNumUnpackStream) if (type == k7zIdNumUnpackStream)
{ {
*numUnpackStreams = 0; *numUnpackStreams = 0;
for (i = 0; i < numFolders; i++) for (i = 0; i < numFolders; i++)
{ {
uint32_t numStreams = 0; uint32_t numStreams = 0;
RINOK(SzReadNumber32(sd, &numStreams)); int result = SzReadNumber32(sd, &numStreams);
if (result != 0)
return result;
folders[i].NumUnpackStreams = numStreams; folders[i].NumUnpackStreams = numStreams;
*numUnpackStreams += numStreams; *numUnpackStreams += numStreams;
} }
@ -750,7 +874,9 @@ static SRes SzReadSubStreamsInfo(
break; break;
if (type == k7zIdEnd) if (type == k7zIdEnd)
break; break;
RINOK(SzSkeepData(sd)); result = SzSkeepData(sd);
if (result != 0)
return result;
} }
if (*numUnpackStreams == 0) if (*numUnpackStreams == 0)
@ -762,11 +888,14 @@ static SRes SzReadSubStreamsInfo(
else else
{ {
*unpackSizes = (uint64_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint64_t)); *unpackSizes = (uint64_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint64_t));
RINOM(*unpackSizes); if (*unpackSizes == 0)
return SZ_ERROR_MEM;
*digestsDefined = (uint8_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint8_t)); *digestsDefined = (uint8_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint8_t));
RINOM(*digestsDefined); if (*digestsDefined == 0)
return SZ_ERROR_MEM;
*digests = (uint32_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint32_t)); *digests = (uint32_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint32_t));
RINOM(*digests); if (*digests == 0)
return SZ_ERROR_MEM;
} }
for (i = 0; i < numFolders; i++) for (i = 0; i < numFolders; i++)
@ -784,15 +913,20 @@ static SRes SzReadSubStreamsInfo(
for (j = 1; j < numSubstreams; j++) for (j = 1; j < numSubstreams; j++)
{ {
uint64_t size; uint64_t size;
RINOK(SzReadNumber(sd, &size)); int result = SzReadNumber(sd, &size);
if (result != 0)
return result;
(*unpackSizes)[si++] = size; (*unpackSizes)[si++] = size;
sum += size; sum += size;
} }
(*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
} }
if (type == k7zIdSize) if (type == k7zIdSize)
{ {
RINOK(SzReadID(sd, &type)); result = SzReadID(sd, &type);
if (result != 0)
return result;
} }
for (i = 0; i < *numUnpackStreams; i++) for (i = 0; i < *numUnpackStreams; i++)
@ -845,15 +979,20 @@ static SRes SzReadSubStreamsInfo(
} }
IAlloc_Free(allocTemp, digestsDefined2); IAlloc_Free(allocTemp, digestsDefined2);
IAlloc_Free(allocTemp, digests2); IAlloc_Free(allocTemp, digests2);
RINOK(res); if (res != 0)
return res;
} }
else if (type == k7zIdEnd) else if (type == k7zIdEnd)
return SZ_OK; return SZ_OK;
else else
{ {
RINOK(SzSkeepData(sd)); result = SzSkeepData(sd);
if (result != 0)
return result;
} }
RINOK(SzReadID(sd, &type)); result = SzReadID(sd, &type);
if (result != 0)
return result;
} }
} }
@ -872,7 +1011,10 @@ static SRes SzReadStreamsInfo(
for (;;) for (;;)
{ {
uint64_t type; uint64_t type;
RINOK(SzReadID(sd, &type)); int result = SzReadID(sd, &type);
if (result != 0)
return result;
if ((uint64_t)(int)type != type) if ((uint64_t)(int)type != type)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
switch((int)type) switch((int)type)
@ -881,19 +1023,26 @@ static SRes SzReadStreamsInfo(
return SZ_OK; return SZ_OK;
case k7zIdPackInfo: case k7zIdPackInfo:
{ {
RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, int result = SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
&p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc);
if (result != 0)
return result;
break; break;
} }
case k7zIdUnpackInfo: case k7zIdUnpackInfo:
{ {
RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); int result = SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp);
if (result != 0)
return result;
break; break;
} }
case k7zIdSubStreamsInfo: case k7zIdSubStreamsInfo:
{ {
RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, int result = SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp);
if (result != 0)
return result;
break; break;
} }
default: default:
@ -958,27 +1107,37 @@ static SRes SzReadHeader2(
uint32_t numFiles = 0; uint32_t numFiles = 0;
CSzFileItem *files = 0; CSzFileItem *files = 0;
uint32_t numEmptyStreams = 0; uint32_t numEmptyStreams = 0;
int result = SzReadID(sd, &type);
RINOK(SzReadID(sd, &type)); if (result != 0)
return result;
if (type == k7zIdArchiveProperties) if (type == k7zIdArchiveProperties)
{ {
RINOK(SzReadArchiveProperties(sd)); result = SzReadArchiveProperties(sd);
RINOK(SzReadID(sd, &type)); if (result != 0)
return result;
result = SzReadID(sd, &type);
if (result != 0)
return result;
} }
if (type == k7zIdMainStreamsInfo) if (type == k7zIdMainStreamsInfo)
{ {
RINOK(SzReadStreamsInfo(sd, result = SzReadStreamsInfo(sd,
&p->dataPos, &p->dataPos,
&p->db, &p->db,
&numUnpackStreams, &numUnpackStreams,
unpackSizes, unpackSizes,
digestsDefined, digestsDefined,
digests, allocMain, allocTemp)); digests, allocMain, allocTemp);
if (result != 0)
return result;
p->dataPos += p->startPosAfterHeader; p->dataPos += p->startPosAfterHeader;
RINOK(SzReadID(sd, &type)); result = SzReadID(sd, &type);
if (result != 0)
return result;
} }
if (type == k7zIdEnd) if (type == k7zIdEnd)
@ -986,7 +1145,9 @@ static SRes SzReadHeader2(
if (type != k7zIdFilesInfo) if (type != k7zIdFilesInfo)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
RINOK(SzReadNumber32(sd, &numFiles)); result = SzReadNumber32(sd, &numFiles);
if (result != 0)
return result;
p->db.NumFiles = numFiles; p->db.NumFiles = numFiles;
MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);
@ -998,41 +1159,54 @@ static SRes SzReadHeader2(
for (;;) for (;;)
{ {
uint64_t size; uint64_t size;
RINOK(SzReadID(sd, &type)); int result = SzReadID(sd, &type);
if (result != 0)
return result;
if (type == k7zIdEnd) if (type == k7zIdEnd)
break; break;
RINOK(SzReadNumber(sd, &size)); result = SzReadNumber(sd, &size);
if (result != 0)
return result;
if (size > sd->Size) if (size > sd->Size)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
if ((uint64_t)(int)type != type) if ((uint64_t)(int)type != type)
{ {
RINOK(SzSkeepDataSize(sd, size)); int result = SzSkeepDataSize(sd, size);
if (result != 0)
return result;
} }
else else
switch((int)type) switch((int)type)
{ {
case k7zIdName: case k7zIdName:
{ {
size_t namesSize; int result = SzReadSwitch(sd);
RINOK(SzReadSwitch(sd)); size_t namesSize = (size_t)size - 1;
namesSize = (size_t)size - 1; if (result != 0)
return result;
if ((namesSize & 1) != 0) if ((namesSize & 1) != 0)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
if (!Buf_Create(&p->FileNames, namesSize, allocMain)) if (!Buf_Create(&p->FileNames, namesSize, allocMain))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
memcpy(p->FileNames.data, sd->Data, namesSize); memcpy(p->FileNames.data, sd->Data, namesSize);
RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets)) result = SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets);
RINOK(SzSkeepDataSize(sd, namesSize)); if (result != 0)
return result;
result = SzSkeepDataSize(sd, namesSize);
if (result != 0)
return result;
break; break;
} }
case k7zIdEmptyStream: case k7zIdEmptyStream:
{ {
RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); int result = SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp);
if (result != 0)
return result;
numEmptyStreams = 0; numEmptyStreams = 0;
for (i = 0; i < numFiles; i++) for (i = 0; i < numFiles; i++)
if ((*emptyStreamVector)[i]) if ((*emptyStreamVector)[i])
@ -1041,13 +1215,20 @@ static SRes SzReadHeader2(
} }
case k7zIdEmptyFile: case k7zIdEmptyFile:
{ {
RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); int result = SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp);
if (result != 0)
return result;
break; break;
} }
case k7zIdWinAttributes: case k7zIdWinAttributes:
{ {
RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); int result = SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp);
RINOK(SzReadSwitch(sd)); if (result != 0)
return result;
result = SzReadSwitch(sd);
if (result != 0)
return result;
for (i = 0; i < numFiles; i++) for (i = 0; i < numFiles; i++)
{ {
CSzFileItem *f = &files[i]; CSzFileItem *f = &files[i];
@ -1056,7 +1237,9 @@ static SRes SzReadHeader2(
f->Attrib = 0; f->Attrib = 0;
if (defined) if (defined)
{ {
RINOK(SzReaduint32_t(sd, &f->Attrib)); result = SzReaduint32_t(sd, &f->Attrib);
if (result != 0)
return result;
} }
} }
IAlloc_Free(allocTemp, *lwtVector); IAlloc_Free(allocTemp, *lwtVector);
@ -1065,9 +1248,14 @@ static SRes SzReadHeader2(
} }
case k7zIdMTime: case k7zIdMTime:
{ {
RINOK(SzReadBoolVector2(sd, int result = SzReadBoolVector2(sd,
numFiles, lwtVector, allocTemp)); numFiles, lwtVector, allocTemp);
RINOK(SzReadSwitch(sd)); if (result != 0)
return result;
result = SzReadSwitch(sd);
if (result != 0)
return result;
for (i = 0; i < numFiles; i++) for (i = 0; i < numFiles; i++)
{ {
CSzFileItem *f = &files[i]; CSzFileItem *f = &files[i];
@ -1076,8 +1264,12 @@ static SRes SzReadHeader2(
f->MTime.Low = f->MTime.High = 0; f->MTime.Low = f->MTime.High = 0;
if (defined) if (defined)
{ {
RINOK(SzReaduint32_t(sd, &f->MTime.Low)); result = SzReaduint32_t(sd, &f->MTime.Low);
RINOK(SzReaduint32_t(sd, &f->MTime.High)); if (result != 0)
return result;
result = SzReaduint32_t(sd, &f->MTime.High);
if (result != 0)
return result;
} }
} }
IAlloc_Free(allocTemp, *lwtVector); IAlloc_Free(allocTemp, *lwtVector);
@ -1086,7 +1278,9 @@ static SRes SzReadHeader2(
} }
default: default:
{ {
RINOK(SzSkeepDataSize(sd, size)); result = SzSkeepDataSize(sd, size);
if (result != 0)
return result;
} }
} }
} }
@ -1170,19 +1364,24 @@ static SRes SzReadAndDecodePackedStreams2(
uint64_t dataStartPos = 0; uint64_t dataStartPos = 0;
uint64_t unpackSize = 0; uint64_t unpackSize = 0;
uint32_t numUnpackStreams = 0; uint32_t numUnpackStreams = 0;
int result = SzReadStreamsInfo(sd, &dataStartPos, p,
RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
&numUnpackStreams, unpackSizes, digestsDefined, digests, &numUnpackStreams, unpackSizes, digestsDefined, digests,
allocTemp, allocTemp)); allocTemp, allocTemp);
if (result != 0)
return result;
dataStartPos += baseOffset; dataStartPos += baseOffset;
if (p->NumFolders != 1) if (p->NumFolders != 1)
return SZ_ERROR_ARCHIVE; return SZ_ERROR_ARCHIVE;
folder = p->Folders; folder = p->Folders;
unpackSize = SzFolder_GetUnpackSize(folder); unpackSize = SzFolder_GetUnpackSize(folder);
RINOK(LookInStream_SeekTo(inStream, dataStartPos)); result = LookInStream_SeekTo(inStream, dataStartPos);
if (result != 0)
return result;
if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
@ -1190,7 +1389,8 @@ static SRes SzReadAndDecodePackedStreams2(
res = SzFolder_Decode(folder, p->PackSizes, res = SzFolder_Decode(folder, p->PackSizes,
inStream, dataStartPos, inStream, dataStartPos,
outBuffer->data, (size_t)unpackSize, allocTemp); outBuffer->data, (size_t)unpackSize, allocTemp);
RINOK(res); if (res != 0)
return res;
if (folder->UnpackCRCDefined) if (folder->UnpackCRCDefined)
if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
return SZ_ERROR_CRC; return SZ_ERROR_CRC;
@ -1236,10 +1436,17 @@ static SRes SzArEx_Open2(
size_t nextHeaderSizeT; size_t nextHeaderSizeT;
uint32_t nextHeaderCRC; uint32_t nextHeaderCRC;
int64_t startArcPos = 0; int64_t startArcPos = 0;
int result = inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR);
RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); if (result != 0)
RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, return result;
SZ_ERROR_NO_ARCHIVE));
result = LookInStream_Read2(inStream, header,
k7zStartHeaderSize,
SZ_ERROR_NO_ARCHIVE);
if (result != 0)
return result;
if (!TestSignatureCandidate(header)) if (!TestSignatureCandidate(header))
return SZ_ERROR_NO_ARCHIVE; return SZ_ERROR_NO_ARCHIVE;
@ -1266,14 +1473,19 @@ static SRes SzArEx_Open2(
{ {
int64_t pos = 0; int64_t pos = 0;
RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); int result = inStream->Seek(inStream, &pos, SZ_SEEK_END);
if (result != 0)
return result;
if ((uint64_t)pos < startArcPos + nextHeaderOffset || if ((uint64_t)pos < startArcPos + nextHeaderOffset ||
(uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || (uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
(uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) (uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
return SZ_ERROR_INPUT_EOF; return SZ_ERROR_INPUT_EOF;
} }
RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset)); result = LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset);
if (result != 0)
return result;
if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
@ -1359,6 +1571,7 @@ SRes SzArEx_Extract(
if (*outBuffer == 0 || *blockIndex != folderIndex) if (*outBuffer == 0 || *blockIndex != folderIndex)
{ {
int result;
CSzFolder *folder = p->db.Folders + folderIndex; CSzFolder *folder = p->db.Folders + folderIndex;
uint64_t unpackSizeSpec = SzFolder_GetUnpackSize(folder); uint64_t unpackSizeSpec = SzFolder_GetUnpackSize(folder);
size_t unpackSize = (size_t)unpackSizeSpec; size_t unpackSize = (size_t)unpackSizeSpec;
@ -1369,8 +1582,9 @@ SRes SzArEx_Extract(
*blockIndex = folderIndex; *blockIndex = folderIndex;
IAlloc_Free(allocMain, *outBuffer); IAlloc_Free(allocMain, *outBuffer);
*outBuffer = 0; *outBuffer = 0;
result = LookInStream_SeekTo(inStream, startOffset);
RINOK(LookInStream_SeekTo(inStream, startOffset)); if (result != 0)
return result;
if (res == SZ_OK) if (res == SZ_OK)
{ {
@ -1381,6 +1595,7 @@ SRes SzArEx_Extract(
if (*outBuffer == 0) if (*outBuffer == 0)
res = SZ_ERROR_MEM; res = SZ_ERROR_MEM;
} }
if (res == SZ_OK) if (res == SZ_OK)
{ {
res = SzFolder_Decode(folder, res = SzFolder_Decode(folder,

41
deps/7zip/7zStream.c vendored
View File

@ -7,18 +7,29 @@
#include "7zTypes.h" #include "7zTypes.h"
SRes SeqInStream_Readuint8_t(ISeqInStream *stream, uint8_t *buf); SRes SeqInStream_Readuint8_t(ISeqInStream *stream, uint8_t *buf)
{
size_t processed = 1;
int result = stream->Read(stream, buf, &processed);
if (result != 0)
return result;
if (processed != 1)
return SZ_ERROR_INPUT_EOF;
return SZ_OK;
}
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{ {
while (size != 0) while (size != 0)
{ {
size_t processed = size; size_t processed = size;
RINOK(stream->Read(stream, buf, &processed)); int result = stream->Read(stream, buf, &processed);
if (result != 0)
return result;
if (processed == 0) if (processed == 0)
return errorType; return errorType;
buf = (void *)((uint8_t *)buf + processed); buf = (void *)((uint8_t *)buf + processed);
size -= processed; size -= processed;
} }
return SZ_OK; return SZ_OK;
} }
@ -28,12 +39,6 @@ SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
} }
SRes SeqInStream_Readuint8_t(ISeqInStream *stream, uint8_t *buf)
{
size_t processed = 1;
RINOK(stream->Read(stream, buf, &processed));
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
}
SRes LookInStream_SeekTo(ILookInStream *stream, uint64_t offset) SRes LookInStream_SeekTo(ILookInStream *stream, uint64_t offset)
{ {
@ -43,24 +48,30 @@ SRes LookInStream_SeekTo(ILookInStream *stream, uint64_t offset)
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
{ {
int result;
const void *lookBuf; const void *lookBuf;
if (*size == 0) if (*size == 0)
return SZ_OK; return SZ_OK;
RINOK(stream->Look(stream, &lookBuf, size)); result = stream->Look(stream, &lookBuf, size);
if (result != 0)
return result;
memcpy(buf, lookBuf, *size); memcpy(buf, lookBuf, *size);
return stream->Skip(stream, *size); return stream->Skip(stream, *size);
} }
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) SRes LookInStream_Read2(ILookInStream *stream,
void *buf, size_t size, SRes errorType)
{ {
while (size != 0) while (size != 0)
{ {
size_t processed = size; size_t processed = size;
RINOK(stream->Read(stream, buf, &processed)); int result = stream->Read(stream, buf, &processed);
if (result != 0)
return result;
if (processed == 0) if (processed == 0)
return errorType; return errorType;
buf = (void *)((uint8_t *)buf + processed); buf = (void *)((uint8_t *)buf + processed);
size -= processed; size -= processed;
} }
return SZ_OK; return SZ_OK;
} }

22
deps/7zip/Lzma2Dec.c vendored
View File

@ -66,14 +66,18 @@ static SRes Lzma2Dec_GetOldProps(uint8_t prop, uint8_t *props)
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc) SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc)
{ {
uint8_t props[LZMA_PROPS_SIZE]; uint8_t props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props)); int result = Lzma2Dec_GetOldProps(prop, props);
if (result != 0)
return result;
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
} }
SRes Lzma2Dec_Allocate(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc) SRes Lzma2Dec_Allocate(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc)
{ {
uint8_t props[LZMA_PROPS_SIZE]; uint8_t props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props)); int result = Lzma2Dec_GetOldProps(prop, props);
if (result != 0)
return result;
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
} }
@ -259,7 +263,8 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, size_t dicLimit,
outSizeProcessed = p->decoder.dicPos - dicPos; outSizeProcessed = p->decoder.dicPos - dicPos;
p->unpackSize -= (uint32_t)outSizeProcessed; p->unpackSize -= (uint32_t)outSizeProcessed;
RINOK(res); if (res != 0)
return res;
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
return res; return res;
@ -321,8 +326,9 @@ SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, uint8_t *dest, size_t *destLen, const ui
SRes Lzma2Decode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, SRes Lzma2Decode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen,
uint8_t prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) uint8_t prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
{ {
CLzma2Dec decoder;
SRes res; SRes res;
int result;
CLzma2Dec decoder;
size_t outSize = *destLen, inSize = *srcLen; size_t outSize = *destLen, inSize = *srcLen;
uint8_t props[LZMA_PROPS_SIZE]; uint8_t props[LZMA_PROPS_SIZE];
@ -333,8 +339,12 @@ SRes Lzma2Decode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *src
decoder.decoder.dic = dest; decoder.decoder.dic = dest;
decoder.decoder.dicBufSize = outSize; decoder.decoder.dicBufSize = outSize;
RINOK(Lzma2Dec_GetOldProps(prop, props)); result = Lzma2Dec_GetOldProps(prop, props);
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); if (result != 0)
return result;
result = LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc);
if (result != 0)
return result;
*srcLen = inSize; *srcLen = inSize;
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);

395
deps/7zip/LzmaDec.c vendored
View File

@ -494,6 +494,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, size_t limit, const uin
{ {
do do
{ {
int result;
size_t limit2 = limit; size_t limit2 = limit;
if (p->checkDicSize == 0) if (p->checkDicSize == 0)
{ {
@ -501,12 +502,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, size_t limit, const uin
if (limit - p->dicPos > rem) if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem; limit2 = p->dicPos + rem;
} }
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); result = LzmaDec_DecodeReal(p, limit2, bufLimit);
if (result != 0)
return result;
if (p->processedPos >= p->prop.dicSize) if (p->processedPos >= p->prop.dicSize)
p->checkDicSize = p->prop.dicSize; p->checkDicSize = p->prop.dicSize;
LzmaDec_WriteRem(p, limit); LzmaDec_WriteRem(p, limit);
} }
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); while (
p->dicPos < limit &&
p->buf < bufLimit &&
p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart) if (p->remainLen > kMatchSpecLenStart)
{ {
@ -517,101 +523,108 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, size_t limit, const uin
typedef enum typedef enum
{ {
DUMMY_ERROR, /* unexpected end of input stream */ DUMMY_ERROR = 0, /* unexpected end of input stream */
DUMMY_LIT, DUMMY_LIT,
DUMMY_MATCH, DUMMY_MATCH,
DUMMY_REP DUMMY_REP
} ELzmaDummy; } ELzmaDummy;
static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const uint8_t *buf, size_t inSize) static ELzmaDummy LzmaDec_TryDummy(
const CLzmaDec *p, const uint8_t *buf, size_t inSize)
{ {
uint32_t range = p->range;
uint32_t codes = p->code;
const uint8_t *bufLimit = buf + inSize;
uint16_t *probs = p->probs;
unsigned state = p->state;
ELzmaDummy res; ELzmaDummy res;
uint32_t bound;
unsigned ttt;
uint32_t range = p->range;
uint32_t codes = p->code;
const uint8_t *bufLimit = buf + inSize;
uint16_t *probs = p->probs;
unsigned state = p->state;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
uint16_t *prob = probs + IsMatch +
(state << kNumPosBitsMax) + posState;
IF_BIT_0_CHECK(prob)
{ {
uint16_t *prob; UPDATE_0_CHECK
uint32_t bound;
unsigned ttt;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
IF_BIT_0_CHECK(prob)
prob = probs + Literal;
if (p->checkDicSize != 0 || p->processedPos != 0)
prob += (LZMA_LIT_SIZE *
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
if (state < kNumLitStates)
{ {
UPDATE_0_CHECK unsigned symbol = 1;
do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
/* if (bufLimit - buf >= 7) return DUMMY_LIT; */
prob = probs + Literal;
if (p->checkDicSize != 0 || p->processedPos != 0)
prob += (LZMA_LIT_SIZE *
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
if (state < kNumLitStates)
{
unsigned symbol = 1;
do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
}
else
{
unsigned matchuint8_t = p->dic[p->dicPos - p->reps[0] +
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
unsigned offs = 0x100;
unsigned symbol = 1;
do
{
unsigned bit;
uint16_t *probLit;
matchuint8_t <<= 1;
bit = (matchuint8_t & offs);
probLit = prob + offs + bit + symbol;
GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
}
while (symbol < 0x100);
}
res = DUMMY_LIT;
} }
else else
{ {
unsigned len; unsigned matchuint8_t = p->dic[p->dicPos - p->reps[0] +
UPDATE_1_CHECK; ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
unsigned offs = 0x100;
unsigned symbol = 1;
do
{
unsigned bit;
uint16_t *probLit;
matchuint8_t <<= 1;
bit = (matchuint8_t & offs);
probLit = prob + offs + bit + symbol;
GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
}
while (symbol < 0x100);
}
res = DUMMY_LIT;
}
else
{
unsigned len;
UPDATE_1_CHECK;
prob = probs + IsRep + state; prob = probs + IsRep + state;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK;
state = 0;
prob = probs + LenCoder;
res = DUMMY_MATCH;
}
else
{
UPDATE_1_CHECK;
res = DUMMY_REP;
prob = probs + IsRepG0 + state;
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
state = 0; prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
prob = probs + LenCoder; IF_BIT_0_CHECK(prob)
res = DUMMY_MATCH; {
UPDATE_0_CHECK;
NORMALIZE_CHECK;
return DUMMY_REP;
}
else
{
UPDATE_1_CHECK;
}
} }
else else
{ {
UPDATE_1_CHECK; UPDATE_1_CHECK;
res = DUMMY_REP; prob = probs + IsRepG1 + state;
prob = probs + IsRepG0 + state;
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK;
NORMALIZE_CHECK;
return DUMMY_REP;
}
else
{
UPDATE_1_CHECK;
}
} }
else else
{ {
UPDATE_1_CHECK; UPDATE_1_CHECK;
prob = probs + IsRepG1 + state; prob = probs + IsRepG2 + state;
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
@ -619,92 +632,83 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const uint8_t *buf, size_t
else else
{ {
UPDATE_1_CHECK; UPDATE_1_CHECK;
prob = probs + IsRepG2 + state;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK;
}
else
{
UPDATE_1_CHECK;
}
} }
} }
state = kNumStates;
prob = probs + RepLenCoder;
} }
state = kNumStates;
prob = probs + RepLenCoder;
}
{
unsigned limit, offset;
uint16_t *probLen = prob + LenChoice;
IF_BIT_0_CHECK(probLen)
{ {
unsigned limit, offset; UPDATE_0_CHECK;
uint16_t *probLen = prob + LenChoice; probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
limit = 1 << kLenNumLowBits;
}
else
{
UPDATE_1_CHECK;
probLen = prob + LenChoice2;
IF_BIT_0_CHECK(probLen) IF_BIT_0_CHECK(probLen)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
probLen = prob + LenLow + (posState << kLenNumLowBits); probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = 0; offset = kLenNumLowSymbols;
limit = 1 << kLenNumLowBits; limit = 1 << kLenNumMidBits;
} }
else else
{ {
UPDATE_1_CHECK; UPDATE_1_CHECK;
probLen = prob + LenChoice2; probLen = prob + LenHigh;
IF_BIT_0_CHECK(probLen) offset = kLenNumLowSymbols + kLenNumMidSymbols;
{ limit = 1 << kLenNumHighBits;
UPDATE_0_CHECK;
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
limit = 1 << kLenNumMidBits;
}
else
{
UPDATE_1_CHECK;
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
limit = 1 << kLenNumHighBits;
}
} }
TREE_DECODE_CHECK(probLen, limit, len);
len += offset;
} }
TREE_DECODE_CHECK(probLen, limit, len);
len += offset;
}
if (state < 4) if (state < 4)
{
unsigned posSlot;
prob = probs + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits);
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{ {
unsigned posSlot; int numDirectBits = ((posSlot >> 1) - 1);
prob = probs + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
kNumPosSlotBits);
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); if (posSlot < kEndPosModelIndex)
if (posSlot >= kStartPosModelIndex)
{ {
int numDirectBits = ((posSlot >> 1) - 1); prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
}
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ else
{
if (posSlot < kEndPosModelIndex) numDirectBits -= kNumAlignBits;
do
{ {
prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; NORMALIZE_CHECK
range >>= 1;
codes -= range & (((codes - range) >> 31) - 1);
/* if (codes >= range) codes -= range; */
} }
else while (--numDirectBits != 0);
prob = probs + Align;
numDirectBits = kNumAlignBits;
}
{
unsigned i = 1;
do
{ {
numDirectBits -= kNumAlignBits; GET_BIT_CHECK(prob + i, i);
do
{
NORMALIZE_CHECK
range >>= 1;
codes -= range & (((codes - range) >> 31) - 1);
/* if (codes >= range) codes -= range; */
}
while (--numDirectBits != 0);
prob = probs + Align;
numDirectBits = kNumAlignBits;
}
{
unsigned i = 1;
do
{
GET_BIT_CHECK(prob + i, i);
}
while (--numDirectBits != 0);
} }
while (--numDirectBits != 0);
} }
} }
} }
@ -713,26 +717,27 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const uint8_t *buf, size_t
return res; return res;
} }
static void LzmaDec_InitRc(CLzmaDec *p, const uint8_t *data) static void LzmaDec_InitRc(CLzmaDec *p, const uint8_t *data)
{ {
p->code = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 8) | ((uint32_t)data[4]); p->code = (
p->range = 0xFFFFFFFF; (uint32_t)data[1] << 24) |
((uint32_t)data[2] << 16) |
((uint32_t)data[3] << 8) |
((uint32_t)data[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0; p->needFlush = 0;
} }
void LzmaDec_InitDicAndState(CLzmaDec *p, bool initDic, bool initState);
void LzmaDec_InitDicAndState(CLzmaDec *p, bool initDic, bool initState) void LzmaDec_InitDicAndState(CLzmaDec *p, bool initDic, bool initState)
{ {
p->needFlush = 1; p->needFlush = 1;
p->remainLen = 0; p->remainLen = 0;
p->tempBufSize = 0; p->tempBufSize = 0;
if (initDic) if (initDic)
{ {
p->processedPos = 0; p->processedPos = 0;
p->checkDicSize = 0; p->checkDicSize = 0;
p->needInitState = 1; p->needInitState = 1;
} }
if (initState) if (initState)
@ -747,17 +752,19 @@ void LzmaDec_Init(CLzmaDec *p)
static void LzmaDec_InitStateReal(CLzmaDec *p) static void LzmaDec_InitStateReal(CLzmaDec *p)
{ {
uint32_t numProbs = Literal + ((uint32_t)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
uint32_t i; uint32_t i;
uint16_t *probs = p->probs; uint32_t numProbs = Literal +
((uint32_t)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
uint16_t *probs = p->probs;
for (i = 0; i < numProbs; i++) for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1; probs[i] = kBitModelTotal >> 1;
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
p->state = 0; p->state = 0;
p->needInitState = 0; p->needInitState = 0;
} }
SRes LzmaDec_DecodeToDic(CLzmaDec *p, size_t dicLimit, const uint8_t *src, size_t *srcLen, SRes LzmaDec_DecodeToDic(CLzmaDec *p, size_t dicLimit,
const uint8_t *src, size_t *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status) ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
size_t inSize = *srcLen; size_t inSize = *srcLen;
@ -772,7 +779,8 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, size_t dicLimit, const uint8_t *src, size_
if (p->needFlush != 0) if (p->needFlush != 0)
{ {
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE;
(*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++; p->tempBuf[p->tempBufSize++] = *src++;
if (p->tempBufSize < RC_INIT_SIZE) if (p->tempBufSize < RC_INIT_SIZE)
{ {
@ -881,36 +889,37 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, size_t dicLimit, const uint8_t *src, size_
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) SRes LzmaDec_DecodeToBuf(CLzmaDec *p, uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
size_t outSize = *destLen; size_t outSize = *destLen;
size_t inSize = *srcLen; size_t inSize = *srcLen;
*srcLen = *destLen = 0; *srcLen = *destLen = 0;
for (;;) for (;;)
{ {
size_t inSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode;
SRes res; SRes res;
ELzmaFinishMode curFinishMode;
size_t inSizeCur = inSize, outSizeCur, dicPos;
if (p->dicPos == p->dicBufSize) if (p->dicPos == p->dicBufSize)
p->dicPos = 0; p->dicPos = 0;
dicPos = p->dicPos; dicPos = p->dicPos;
if (outSize > p->dicBufSize - dicPos) if (outSize > p->dicBufSize - dicPos)
{ {
outSizeCur = p->dicBufSize; outSizeCur = p->dicBufSize;
curFinishMode = LZMA_FINISH_ANY; curFinishMode = LZMA_FINISH_ANY;
} }
else else
{ {
outSizeCur = dicPos + outSize; outSizeCur = dicPos + outSize;
curFinishMode = finishMode; curFinishMode = finishMode;
} }
res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
src += inSizeCur; src += inSizeCur;
inSize -= inSizeCur; inSize -= inSizeCur;
*srcLen += inSizeCur; *srcLen += inSizeCur;
outSizeCur = p->dicPos - dicPos; outSizeCur = p->dicPos - dicPos;
memcpy(dest, p->dic + dicPos, outSizeCur); memcpy(dest, p->dic + dicPos, outSizeCur);
dest += outSizeCur; dest += outSizeCur;
outSize -= outSizeCur; outSize -= outSizeCur;
*destLen += outSizeCur; *destLen += outSizeCur;
if (res != 0) if (res != 0)
return res; return res;
if (outSizeCur == 0 || outSize == 0) if (outSizeCur == 0 || outSize == 0)
@ -944,25 +953,29 @@ SRes LzmaProps_Decode(CLzmaProps *p, const uint8_t *data, unsigned size)
if (size < LZMA_PROPS_SIZE) if (size < LZMA_PROPS_SIZE)
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
else else
dicSize = data[1] | ((uint32_t)data[2] << 8) | ((uint32_t)data[3] << 16) | ((uint32_t)data[4] << 24); dicSize = data[1] |
((uint32_t)data[2] << 8) |
((uint32_t)data[3] << 16) |
((uint32_t)data[4] << 24);
if (dicSize < LZMA_DIC_MIN) if (dicSize < LZMA_DIC_MIN)
dicSize = LZMA_DIC_MIN; dicSize = LZMA_DIC_MIN;
p->dicSize = dicSize; p->dicSize = dicSize;
d = data[0]; d = data[0];
if (d >= (9 * 5 * 5)) if (d >= (9 * 5 * 5))
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
p->lc = d % 9; p->lc = d % 9;
d /= 9; d /= 9;
p->pb = d / 5; p->pb = d / 5;
p->lp = d % 5; p->lp = d % 5;
return SZ_OK; return SZ_OK;
} }
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) static SRes LzmaDec_AllocateProbs2(
CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
{ {
uint32_t numProbs = LzmaProps_GetNumProbs(propNew); uint32_t numProbs = LzmaProps_GetNumProbs(propNew);
if (p->probs == 0 || numProbs != p->numProbs) if (p->probs == 0 || numProbs != p->numProbs)
@ -976,22 +989,37 @@ static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAl
return SZ_OK; return SZ_OK;
} }
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const uint8_t *props, unsigned propsSize, ISzAlloc *alloc) SRes LzmaDec_AllocateProbs(CLzmaDec *p,
const uint8_t *props, unsigned propsSize, ISzAlloc *alloc)
{ {
CLzmaProps propNew; CLzmaProps propNew;
RINOK(LzmaProps_Decode(&propNew, props, propsSize)); int result = LzmaProps_Decode(&propNew, props, propsSize);
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); if (result != 0)
p->prop = propNew; return result;
result = LzmaDec_AllocateProbs2(p, &propNew, alloc);
if (result != 0)
return result;
p->prop = propNew;
return SZ_OK; return SZ_OK;
} }
SRes LzmaDec_Allocate(CLzmaDec *p, const uint8_t *props, unsigned propsSize, ISzAlloc *alloc) SRes LzmaDec_Allocate(CLzmaDec *p, const uint8_t *props,
unsigned propsSize, ISzAlloc *alloc)
{ {
CLzmaProps propNew; CLzmaProps propNew;
size_t dicBufSize; size_t dicBufSize;
RINOK(LzmaProps_Decode(&propNew, props, propsSize)); int result = LzmaProps_Decode(&propNew, props, propsSize);
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
if (result != 0)
return result;
result = LzmaDec_AllocateProbs2(p, &propNew, alloc);
if (result != 0)
return result;
dicBufSize = propNew.dicSize; dicBufSize = propNew.dicSize;
if (p->dic == 0 || dicBufSize != p->dicBufSize) if (p->dic == 0 || dicBufSize != p->dicBufSize)
{ {
LzmaDec_FreeDict(p, alloc); LzmaDec_FreeDict(p, alloc);
@ -1007,7 +1035,8 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const uint8_t *props, unsigned propsSize, ISz
return SZ_OK; return SZ_OK;
} }
SRes LzmaDecode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, SRes LzmaDecode(uint8_t *dest, size_t *destLen,
const uint8_t *src, size_t *srcLen,
const uint8_t *propData, unsigned propSize, ELzmaFinishMode finishMode, const uint8_t *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc) ELzmaStatus *status, ISzAlloc *alloc)
{ {

1160
deps/7zip/LzmaEnc.c vendored

File diff suppressed because it is too large Load Diff