diff options
author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2023-06-21 00:00:00 +0000 |
---|---|---|
committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2023-12-17 14:59:19 +0500 |
commit | 5b39dc76f1bc82f941d5c800ab9f34407a06b53a (patch) | |
tree | fe5e17420300b715021a76328444088d32047963 /C/XzIn.c | |
parent | 93be7d4abfd4233228f58ee1fbbcd76d91be66a4 (diff) | |
download | 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.tar.gz 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.tar.bz2 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.zip |
23.0123.01
Diffstat (limited to 'C/XzIn.c')
-rw-r--r-- | C/XzIn.c | 75 |
1 files changed, 45 insertions, 30 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* XzIn.c - Xz input | 1 | /* XzIn.c - Xz input |
2 | 2021-09-04 : Igor Pavlov : Public domain */ | 2 | 2023-04-02 : Igor Pavlov : Public domain */ |
3 | 3 | ||
4 | #include "Precomp.h" | 4 | #include "Precomp.h" |
5 | 5 | ||
@@ -15,11 +15,13 @@ | |||
15 | #define XZ_FOOTER_SIG_CHECK(p) ((p)[0] == XZ_FOOTER_SIG_0 && (p)[1] == XZ_FOOTER_SIG_1) | 15 | #define XZ_FOOTER_SIG_CHECK(p) ((p)[0] == XZ_FOOTER_SIG_0 && (p)[1] == XZ_FOOTER_SIG_1) |
16 | 16 | ||
17 | 17 | ||
18 | SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream) | 18 | SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStreamPtr inStream) |
19 | { | 19 | { |
20 | Byte sig[XZ_STREAM_HEADER_SIZE]; | 20 | Byte sig[XZ_STREAM_HEADER_SIZE]; |
21 | RINOK(SeqInStream_Read2(inStream, sig, XZ_STREAM_HEADER_SIZE, SZ_ERROR_NO_ARCHIVE)); | 21 | size_t processedSize = XZ_STREAM_HEADER_SIZE; |
22 | if (memcmp(sig, XZ_SIG, XZ_SIG_SIZE) != 0) | 22 | RINOK(SeqInStream_ReadMax(inStream, sig, &processedSize)) |
23 | if (processedSize != XZ_STREAM_HEADER_SIZE | ||
24 | || memcmp(sig, XZ_SIG, XZ_SIG_SIZE) != 0) | ||
23 | return SZ_ERROR_NO_ARCHIVE; | 25 | return SZ_ERROR_NO_ARCHIVE; |
24 | return Xz_ParseHeader(p, sig); | 26 | return Xz_ParseHeader(p, sig); |
25 | } | 27 | } |
@@ -29,12 +31,12 @@ SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream) | |||
29 | if (s == 0) return SZ_ERROR_ARCHIVE; \ | 31 | if (s == 0) return SZ_ERROR_ARCHIVE; \ |
30 | pos += s; } | 32 | pos += s; } |
31 | 33 | ||
32 | SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, BoolInt *isIndex, UInt32 *headerSizeRes) | 34 | SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStreamPtr inStream, BoolInt *isIndex, UInt32 *headerSizeRes) |
33 | { | 35 | { |
34 | Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; | 36 | Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; |
35 | unsigned headerSize; | 37 | unsigned headerSize; |
36 | *headerSizeRes = 0; | 38 | *headerSizeRes = 0; |
37 | RINOK(SeqInStream_ReadByte(inStream, &header[0])); | 39 | RINOK(SeqInStream_ReadByte(inStream, &header[0])) |
38 | headerSize = (unsigned)header[0]; | 40 | headerSize = (unsigned)header[0]; |
39 | if (headerSize == 0) | 41 | if (headerSize == 0) |
40 | { | 42 | { |
@@ -46,7 +48,12 @@ SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, BoolInt *isIndex, U | |||
46 | *isIndex = False; | 48 | *isIndex = False; |
47 | headerSize = (headerSize << 2) + 4; | 49 | headerSize = (headerSize << 2) + 4; |
48 | *headerSizeRes = headerSize; | 50 | *headerSizeRes = headerSize; |
49 | RINOK(SeqInStream_Read(inStream, header + 1, headerSize - 1)); | 51 | { |
52 | size_t processedSize = headerSize - 1; | ||
53 | RINOK(SeqInStream_ReadMax(inStream, header + 1, &processedSize)) | ||
54 | if (processedSize != headerSize - 1) | ||
55 | return SZ_ERROR_INPUT_EOF; | ||
56 | } | ||
50 | return XzBlock_Parse(p, header); | 57 | return XzBlock_Parse(p, header); |
51 | } | 58 | } |
52 | 59 | ||
@@ -58,7 +65,9 @@ UInt64 Xz_GetUnpackSize(const CXzStream *p) | |||
58 | UInt64 size = 0; | 65 | UInt64 size = 0; |
59 | size_t i; | 66 | size_t i; |
60 | for (i = 0; i < p->numBlocks; i++) | 67 | for (i = 0; i < p->numBlocks; i++) |
61 | ADD_SIZE_CHECK(size, p->blocks[i].unpackSize); | 68 | { |
69 | ADD_SIZE_CHECK(size, p->blocks[i].unpackSize) | ||
70 | } | ||
62 | return size; | 71 | return size; |
63 | } | 72 | } |
64 | 73 | ||
@@ -67,12 +76,14 @@ UInt64 Xz_GetPackSize(const CXzStream *p) | |||
67 | UInt64 size = 0; | 76 | UInt64 size = 0; |
68 | size_t i; | 77 | size_t i; |
69 | for (i = 0; i < p->numBlocks; i++) | 78 | for (i = 0; i < p->numBlocks; i++) |
70 | ADD_SIZE_CHECK(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3); | 79 | { |
80 | ADD_SIZE_CHECK(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3) | ||
81 | } | ||
71 | return size; | 82 | return size; |
72 | } | 83 | } |
73 | 84 | ||
74 | /* | 85 | /* |
75 | SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream) | 86 | SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStreamPtr inStream) |
76 | { | 87 | { |
77 | return SeqInStream_Read(inStream, p->check, XzFlags_GetCheckSize(f)); | 88 | return SeqInStream_Read(inStream, p->check, XzFlags_GetCheckSize(f)); |
78 | } | 89 | } |
@@ -93,7 +104,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAllocPt | |||
93 | 104 | ||
94 | { | 105 | { |
95 | UInt64 numBlocks64; | 106 | UInt64 numBlocks64; |
96 | READ_VARINT_AND_CHECK(buf, pos, size, &numBlocks64); | 107 | READ_VARINT_AND_CHECK(buf, pos, size, &numBlocks64) |
97 | numBlocks = (size_t)numBlocks64; | 108 | numBlocks = (size_t)numBlocks64; |
98 | if (numBlocks != numBlocks64 || numBlocks * 2 > size) | 109 | if (numBlocks != numBlocks64 || numBlocks * 2 > size) |
99 | return SZ_ERROR_ARCHIVE; | 110 | return SZ_ERROR_ARCHIVE; |
@@ -110,8 +121,8 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAllocPt | |||
110 | for (i = 0; i < numBlocks; i++) | 121 | for (i = 0; i < numBlocks; i++) |
111 | { | 122 | { |
112 | CXzBlockSizes *block = &p->blocks[i]; | 123 | CXzBlockSizes *block = &p->blocks[i]; |
113 | READ_VARINT_AND_CHECK(buf, pos, size, &block->totalSize); | 124 | READ_VARINT_AND_CHECK(buf, pos, size, &block->totalSize) |
114 | READ_VARINT_AND_CHECK(buf, pos, size, &block->unpackSize); | 125 | READ_VARINT_AND_CHECK(buf, pos, size, &block->unpackSize) |
115 | if (block->totalSize == 0) | 126 | if (block->totalSize == 0) |
116 | return SZ_ERROR_ARCHIVE; | 127 | return SZ_ERROR_ARCHIVE; |
117 | } | 128 | } |
@@ -122,7 +133,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAllocPt | |||
122 | return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; | 133 | return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; |
123 | } | 134 | } |
124 | 135 | ||
125 | static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAllocPtr alloc) | 136 | static SRes Xz_ReadIndex(CXzStream *p, ILookInStreamPtr stream, UInt64 indexSize, ISzAllocPtr alloc) |
126 | { | 137 | { |
127 | SRes res; | 138 | SRes res; |
128 | size_t size; | 139 | size_t size; |
@@ -142,14 +153,14 @@ static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, | |||
142 | return res; | 153 | return res; |
143 | } | 154 | } |
144 | 155 | ||
145 | static SRes LookInStream_SeekRead_ForArc(ILookInStream *stream, UInt64 offset, void *buf, size_t size) | 156 | static SRes LookInStream_SeekRead_ForArc(ILookInStreamPtr stream, UInt64 offset, void *buf, size_t size) |
146 | { | 157 | { |
147 | RINOK(LookInStream_SeekTo(stream, offset)); | 158 | RINOK(LookInStream_SeekTo(stream, offset)) |
148 | return LookInStream_Read(stream, buf, size); | 159 | return LookInStream_Read(stream, buf, size); |
149 | /* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */ | 160 | /* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */ |
150 | } | 161 | } |
151 | 162 | ||
152 | static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAllocPtr alloc) | 163 | static SRes Xz_ReadBackward(CXzStream *p, ILookInStreamPtr stream, Int64 *startOffset, ISzAllocPtr alloc) |
153 | { | 164 | { |
154 | UInt64 indexSize; | 165 | UInt64 indexSize; |
155 | Byte buf[XZ_STREAM_FOOTER_SIZE]; | 166 | Byte buf[XZ_STREAM_FOOTER_SIZE]; |
@@ -159,7 +170,7 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff | |||
159 | return SZ_ERROR_NO_ARCHIVE; | 170 | return SZ_ERROR_NO_ARCHIVE; |
160 | 171 | ||
161 | pos -= XZ_STREAM_FOOTER_SIZE; | 172 | pos -= XZ_STREAM_FOOTER_SIZE; |
162 | RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)); | 173 | RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)) |
163 | 174 | ||
164 | if (!XZ_FOOTER_SIG_CHECK(buf + 10)) | 175 | if (!XZ_FOOTER_SIG_CHECK(buf + 10)) |
165 | { | 176 | { |
@@ -174,7 +185,7 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff | |||
174 | 185 | ||
175 | i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos; | 186 | i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos; |
176 | pos -= i; | 187 | pos -= i; |
177 | RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i)); | 188 | RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i)) |
178 | total += (UInt32)i; | 189 | total += (UInt32)i; |
179 | for (; i != 0; i--) | 190 | for (; i != 0; i--) |
180 | if (temp[i - 1] != 0) | 191 | if (temp[i - 1] != 0) |
@@ -193,7 +204,7 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff | |||
193 | if (pos < XZ_STREAM_FOOTER_SIZE) | 204 | if (pos < XZ_STREAM_FOOTER_SIZE) |
194 | return SZ_ERROR_NO_ARCHIVE; | 205 | return SZ_ERROR_NO_ARCHIVE; |
195 | pos -= XZ_STREAM_FOOTER_SIZE; | 206 | pos -= XZ_STREAM_FOOTER_SIZE; |
196 | RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)); | 207 | RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)) |
197 | if (!XZ_FOOTER_SIG_CHECK(buf + 10)) | 208 | if (!XZ_FOOTER_SIG_CHECK(buf + 10)) |
198 | return SZ_ERROR_NO_ARCHIVE; | 209 | return SZ_ERROR_NO_ARCHIVE; |
199 | } | 210 | } |
@@ -217,8 +228,8 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff | |||
217 | return SZ_ERROR_ARCHIVE; | 228 | return SZ_ERROR_ARCHIVE; |
218 | 229 | ||
219 | pos -= indexSize; | 230 | pos -= indexSize; |
220 | RINOK(LookInStream_SeekTo(stream, pos)); | 231 | RINOK(LookInStream_SeekTo(stream, pos)) |
221 | RINOK(Xz_ReadIndex(p, stream, indexSize, alloc)); | 232 | RINOK(Xz_ReadIndex(p, stream, indexSize, alloc)) |
222 | 233 | ||
223 | { | 234 | { |
224 | UInt64 totalSize = Xz_GetPackSize(p); | 235 | UInt64 totalSize = Xz_GetPackSize(p); |
@@ -227,7 +238,7 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff | |||
227 | || pos < totalSize + XZ_STREAM_HEADER_SIZE) | 238 | || pos < totalSize + XZ_STREAM_HEADER_SIZE) |
228 | return SZ_ERROR_ARCHIVE; | 239 | return SZ_ERROR_ARCHIVE; |
229 | pos -= (totalSize + XZ_STREAM_HEADER_SIZE); | 240 | pos -= (totalSize + XZ_STREAM_HEADER_SIZE); |
230 | RINOK(LookInStream_SeekTo(stream, pos)); | 241 | RINOK(LookInStream_SeekTo(stream, pos)) |
231 | *startOffset = (Int64)pos; | 242 | *startOffset = (Int64)pos; |
232 | } | 243 | } |
233 | { | 244 | { |
@@ -236,7 +247,7 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff | |||
236 | SecToRead_CreateVTable(&secToRead); | 247 | SecToRead_CreateVTable(&secToRead); |
237 | secToRead.realStream = stream; | 248 | secToRead.realStream = stream; |
238 | 249 | ||
239 | RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt)); | 250 | RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt)) |
240 | return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE; | 251 | return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE; |
241 | } | 252 | } |
242 | } | 253 | } |
@@ -274,7 +285,9 @@ UInt64 Xzs_GetUnpackSize(const CXzs *p) | |||
274 | UInt64 size = 0; | 285 | UInt64 size = 0; |
275 | size_t i; | 286 | size_t i; |
276 | for (i = 0; i < p->num; i++) | 287 | for (i = 0; i < p->num; i++) |
277 | ADD_SIZE_CHECK(size, Xz_GetUnpackSize(&p->streams[i])); | 288 | { |
289 | ADD_SIZE_CHECK(size, Xz_GetUnpackSize(&p->streams[i])) | ||
290 | } | ||
278 | return size; | 291 | return size; |
279 | } | 292 | } |
280 | 293 | ||
@@ -284,15 +297,17 @@ UInt64 Xzs_GetPackSize(const CXzs *p) | |||
284 | UInt64 size = 0; | 297 | UInt64 size = 0; |
285 | size_t i; | 298 | size_t i; |
286 | for (i = 0; i < p->num; i++) | 299 | for (i = 0; i < p->num; i++) |
287 | ADD_SIZE_CHECK(size, Xz_GetTotalSize(&p->streams[i])); | 300 | { |
301 | ADD_SIZE_CHECK(size, Xz_GetTotalSize(&p->streams[i])) | ||
302 | } | ||
288 | return size; | 303 | return size; |
289 | } | 304 | } |
290 | */ | 305 | */ |
291 | 306 | ||
292 | SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAllocPtr alloc) | 307 | SRes Xzs_ReadBackward(CXzs *p, ILookInStreamPtr stream, Int64 *startOffset, ICompressProgressPtr progress, ISzAllocPtr alloc) |
293 | { | 308 | { |
294 | Int64 endOffset = 0; | 309 | Int64 endOffset = 0; |
295 | RINOK(ILookInStream_Seek(stream, &endOffset, SZ_SEEK_END)); | 310 | RINOK(ILookInStream_Seek(stream, &endOffset, SZ_SEEK_END)) |
296 | *startOffset = endOffset; | 311 | *startOffset = endOffset; |
297 | for (;;) | 312 | for (;;) |
298 | { | 313 | { |
@@ -301,7 +316,7 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr | |||
301 | Xz_Construct(&st); | 316 | Xz_Construct(&st); |
302 | res = Xz_ReadBackward(&st, stream, startOffset, alloc); | 317 | res = Xz_ReadBackward(&st, stream, startOffset, alloc); |
303 | st.startOffset = (UInt64)*startOffset; | 318 | st.startOffset = (UInt64)*startOffset; |
304 | RINOK(res); | 319 | RINOK(res) |
305 | if (p->num == p->numAllocated) | 320 | if (p->num == p->numAllocated) |
306 | { | 321 | { |
307 | const size_t newNum = p->num + p->num / 4 + 1; | 322 | const size_t newNum = p->num + p->num / 4 + 1; |
@@ -317,7 +332,7 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr | |||
317 | p->streams[p->num++] = st; | 332 | p->streams[p->num++] = st; |
318 | if (*startOffset == 0) | 333 | if (*startOffset == 0) |
319 | break; | 334 | break; |
320 | RINOK(LookInStream_SeekTo(stream, (UInt64)*startOffset)); | 335 | RINOK(LookInStream_SeekTo(stream, (UInt64)*startOffset)) |
321 | if (progress && ICompressProgress_Progress(progress, (UInt64)(endOffset - *startOffset), (UInt64)(Int64)-1) != SZ_OK) | 336 | if (progress && ICompressProgress_Progress(progress, (UInt64)(endOffset - *startOffset), (UInt64)(Int64)-1) != SZ_OK) |
322 | return SZ_ERROR_PROGRESS; | 337 | return SZ_ERROR_PROGRESS; |
323 | } | 338 | } |