diff options
Diffstat (limited to 'src/libs/7zip/unix/C/XzIn.c')
-rw-r--r-- | src/libs/7zip/unix/C/XzIn.c | 55 |
1 files changed, 28 insertions, 27 deletions
diff --git a/src/libs/7zip/unix/C/XzIn.c b/src/libs/7zip/unix/C/XzIn.c index f8ea86315..ed9eac31a 100644 --- a/src/libs/7zip/unix/C/XzIn.c +++ b/src/libs/7zip/unix/C/XzIn.c @@ -1,5 +1,7 @@ /* XzIn.c - Xz input -2009-06-19 : Igor Pavlov : Public domain */ +2014-12-30 : Igor Pavlov : Public domain */ + +#include "Precomp.h" #include <string.h> @@ -70,7 +72,7 @@ SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream) static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc) { - size_t i, numBlocks, crcStartPos, pos = 1; + size_t i, numBlocks, pos = 1; UInt32 crc; if (size < 5 || buf[0] != 0) @@ -88,8 +90,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc * if (numBlocks != numBlocks64 || numBlocks * 2 > size) return SZ_ERROR_ARCHIVE; } - - crcStartPos = pos; + Xz_Free(p, alloc); if (numBlocks != 0) { @@ -149,44 +150,43 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff RINOK(SeekFromCur(stream, startOffset)); RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE)); - + if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) { - Int64 i = 0; + UInt32 total = 0; *startOffset += XZ_STREAM_FOOTER_SIZE; for (;;) { - int j; - size_t processedSize; + size_t i; #define TEMP_BUF_SIZE (1 << 10) Byte tempBuf[TEMP_BUF_SIZE]; - if (*startOffset < XZ_STREAM_FOOTER_SIZE || i > (1 << 16)) + if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16)) return SZ_ERROR_NO_ARCHIVE; - processedSize = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset; - i += processedSize; - *startOffset = -(Int64)processedSize; + i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset; + total += (UInt32)i; + *startOffset = -(Int64)i; RINOK(SeekFromCur(stream, startOffset)); - RINOK(LookInStream_Read2(stream, tempBuf, processedSize, SZ_ERROR_NO_ARCHIVE)); - for (j = (int)processedSize; j >= 1; j--) // FIXED j >= 0 => j >= 1 - if (tempBuf[j -1] != 0) + RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE)); + for (; i != 0; i--) + if (tempBuf[i - 1] != 0) break; - if (j != 0) + if (i != 0) { - if ((j & 3) != 0) - return SZ_ERROR_NO_ARCHIVE; - *startOffset += j; - if (*startOffset < XZ_STREAM_FOOTER_SIZE) - return SZ_ERROR_NO_ARCHIVE; - *startOffset -= XZ_STREAM_FOOTER_SIZE; - RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET)); - RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE)); - if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) + if ((i & 3) != 0) return SZ_ERROR_NO_ARCHIVE; + *startOffset += i; break; } } + if (*startOffset < XZ_STREAM_FOOTER_SIZE) + return SZ_ERROR_NO_ARCHIVE; + *startOffset -= XZ_STREAM_FOOTER_SIZE; + RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET)); + RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE)); + if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) + return SZ_ERROR_NO_ARCHIVE; } - + p->flags = (CXzStreamFlags)GetBe16(buf + 8); if (!XzFlags_IsSupported(p->flags)) @@ -291,7 +291,8 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr if (data == 0) return SZ_ERROR_MEM; p->numAllocated = newNum; - memcpy(data, p->streams, p->num * sizeof(CXzStream)); + if (p->num != 0) + memcpy(data, p->streams, p->num * sizeof(CXzStream)); alloc->Free(alloc, p->streams); p->streams = (CXzStream *)data; } |