summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/C/XzIn.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/C/XzIn.c')
-rw-r--r--3rdparty/lzma/C/XzIn.c74
1 files changed, 41 insertions, 33 deletions
diff --git a/3rdparty/lzma/C/XzIn.c b/3rdparty/lzma/C/XzIn.c
index 4ba87a2cfc6..07b1cc39516 100644
--- a/3rdparty/lzma/C/XzIn.c
+++ b/3rdparty/lzma/C/XzIn.c
@@ -1,5 +1,7 @@
/* XzIn.c - Xz input
-2011-02-01 : Igor Pavlov : Public domain */
+2015-11-08 : 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 numBlocks, pos = 1;
UInt32 crc;
if (size < 5 || buf[0] != 0)
@@ -89,10 +91,10 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
return SZ_ERROR_ARCHIVE;
}
- crcStartPos = pos;
Xz_Free(p, alloc);
if (numBlocks != 0)
{
+ size_t i;
p->numBlocks = numBlocks;
p->numBlocksAllocated = numBlocks;
p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
@@ -133,55 +135,58 @@ static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize,
return res;
}
-static SRes SeekFromCur(ILookInStream *inStream, Int64 *res)
+static SRes LookInStream_SeekRead_ForArc(ILookInStream *stream, UInt64 offset, void *buf, size_t size)
{
- return inStream->Seek(inStream, res, SZ_SEEK_CUR);
+ RINOK(LookInStream_SeekTo(stream, offset));
+ return LookInStream_Read(stream, buf, size);
+ /* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */
}
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc)
{
UInt64 indexSize;
Byte buf[XZ_STREAM_FOOTER_SIZE];
+ UInt64 pos = *startOffset;
- if ((*startOffset & 3) != 0 || *startOffset < XZ_STREAM_FOOTER_SIZE)
+ if ((pos & 3) != 0 || pos < XZ_STREAM_FOOTER_SIZE)
return SZ_ERROR_NO_ARCHIVE;
- *startOffset = -XZ_STREAM_FOOTER_SIZE;
- RINOK(SeekFromCur(stream, startOffset));
- RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
+ pos -= XZ_STREAM_FOOTER_SIZE;
+ RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
{
UInt32 total = 0;
- *startOffset += XZ_STREAM_FOOTER_SIZE;
+ pos += XZ_STREAM_FOOTER_SIZE;
+
for (;;)
{
size_t i;
#define TEMP_BUF_SIZE (1 << 10)
- Byte tempBuf[TEMP_BUF_SIZE];
- if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
- return SZ_ERROR_NO_ARCHIVE;
- i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
+ Byte temp[TEMP_BUF_SIZE];
+
+ i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos;
+ pos -= i;
+ RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i));
total += (UInt32)i;
- *startOffset = -(Int64)i;
- RINOK(SeekFromCur(stream, startOffset));
- RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE));
for (; i != 0; i--)
- if (tempBuf[i - 1] != 0)
+ if (temp[i - 1] != 0)
break;
if (i != 0)
{
if ((i & 3) != 0)
return SZ_ERROR_NO_ARCHIVE;
- *startOffset += i;
+ pos += i;
break;
}
+ if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
+ return SZ_ERROR_NO_ARCHIVE;
}
- if (*startOffset < XZ_STREAM_FOOTER_SIZE)
+
+ if (pos < 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));
+ pos -= XZ_STREAM_FOOTER_SIZE;
+ RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
return SZ_ERROR_NO_ARCHIVE;
}
@@ -196,20 +201,22 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2;
- *startOffset = -(Int64)(indexSize + XZ_STREAM_FOOTER_SIZE);
- RINOK(SeekFromCur(stream, startOffset));
+ if (pos < indexSize)
+ return SZ_ERROR_ARCHIVE;
+ pos -= indexSize;
+ RINOK(LookInStream_SeekTo(stream, pos));
RINOK(Xz_ReadIndex(p, stream, indexSize, alloc));
{
UInt64 totalSize = Xz_GetPackSize(p);
- UInt64 sum = XZ_STREAM_HEADER_SIZE + totalSize + indexSize;
- if (totalSize == XZ_SIZE_OVERFLOW ||
- sum >= ((UInt64)1 << 63) ||
- totalSize >= ((UInt64)1 << 63))
+ if (totalSize == XZ_SIZE_OVERFLOW
+ || totalSize >= ((UInt64)1 << 63)
+ || pos < totalSize + XZ_STREAM_HEADER_SIZE)
return SZ_ERROR_ARCHIVE;
- *startOffset = -(Int64)sum;
- RINOK(SeekFromCur(stream, startOffset));
+ pos -= (totalSize + XZ_STREAM_HEADER_SIZE);
+ RINOK(LookInStream_SeekTo(stream, pos));
+ *startOffset = pos;
}
{
CXzStreamFlags headerFlags;
@@ -290,14 +297,15 @@ 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;
}
p->streams[p->num++] = st;
if (*startOffset == 0)
break;
- RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
+ RINOK(LookInStream_SeekTo(stream, *startOffset));
if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)
return SZ_ERROR_PROGRESS;
}