static UString ParseDString(const Byte *data, unsigned size) { UString res; if (size > 0) { wchar_t *p; Byte type = data[0]; if (type == 8) { p = res.GetBuf(size); for (unsigned i = 1; i < size; i++) { wchar_t c = data[i]; if (c == 0) break; *p++ = c; } } else if (type == 16) { p = res.GetBuf(size / 2); for (unsigned i = 1; i + 2 <= size; i += 2) { wchar_t c = GetBe16(data + i); if (c == 0) break; *p++ = c; } } else return L"[unknow]"; *p = 0; res.ReleaseBuf_SetLen((unsigned)(p - (const wchar_t *)res)); } return res; }
bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage) { NWindows::NFile::NIO::CInFile file; if (!file.Open(fileName)) return false; UInt64 fileSize; if (!file.GetLength(fileSize)) return false; if (fileSize >= ((UInt32)1 << 31) - 32) return false; UString u; if (codePage == MY__CP_UTF16 || codePage == MY__CP_UTF16BE) { if ((fileSize & 1) != 0) return false; CByteArr buf((size_t)fileSize); UInt32 processed; if (!file.Read(buf, (UInt32)fileSize, processed)) return false; if (processed != fileSize) return false; file.Close(); unsigned num = (unsigned)fileSize / 2; wchar_t *p = u.GetBuf(num); if (codePage == MY__CP_UTF16) for (unsigned i = 0; i < num; i++) { wchar_t c = GetUi16(buf + i * 2); if (c == 0) return false; p[i] = c; } else for (unsigned i = 0; i < num; i++) { wchar_t c = (wchar_t)GetBe16(buf + i * 2); if (c == 0) return false; p[i] = c; } p[num] = 0; u.ReleaseBuf_SetLen(num); } else { AString s; char *p = s.GetBuf((unsigned)fileSize); UInt32 processed; if (!file.Read(p, (UInt32)fileSize, processed)) return false; if (processed != fileSize) return false; file.Close(); s.ReleaseBuf_CalcLen((unsigned)processed); if (s.Len() != processed) return false; // #ifdef CP_UTF8 if (codePage == CP_UTF8) { if (!ConvertUTF8ToUnicode(s, u)) return false; } else // #endif MultiByteToUnicodeString2(u, s, codePage); } const wchar_t kGoodBOM = 0xFEFF; const wchar_t kBadBOM = 0xFFFE; UString s; unsigned i = 0; for (; i < u.Len() && u[i] == kGoodBOM; i++); for (; i < u.Len(); i++) { wchar_t c = u[i]; if (c == kGoodBOM || c == kBadBOM) return false; if (c == L'\n' || c == 0xD) { AddName(strings, s); s.Empty(); } else s += c; } AddName(strings, s); return true; }
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAllocPtr alloc) { UInt64 indexSize; Byte buf[XZ_STREAM_FOOTER_SIZE]; UInt64 pos = *startOffset; if ((pos & 3) != 0 || pos < XZ_STREAM_FOOTER_SIZE) return SZ_ERROR_NO_ARCHIVE; pos -= XZ_STREAM_FOOTER_SIZE; RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)); if (!XZ_FOOTER_SIG_CHECK(buf + 10)) { UInt32 total = 0; pos += XZ_STREAM_FOOTER_SIZE; for (;;) { size_t i; #define TEMP_BUF_SIZE (1 << 10) 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; for (; i != 0; i--) if (temp[i - 1] != 0) break; if (i != 0) { if ((i & 3) != 0) return SZ_ERROR_NO_ARCHIVE; pos += i; break; } if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16)) return SZ_ERROR_NO_ARCHIVE; } if (pos < XZ_STREAM_FOOTER_SIZE) return SZ_ERROR_NO_ARCHIVE; pos -= XZ_STREAM_FOOTER_SIZE; RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)); if (!XZ_FOOTER_SIG_CHECK(buf + 10)) return SZ_ERROR_NO_ARCHIVE; } p->flags = (CXzStreamFlags)GetBe16(buf + 8); if (!XzFlags_IsSupported(p->flags)) return SZ_ERROR_UNSUPPORTED; if (GetUi32(buf) != CrcCalc(buf + 4, 6)) return SZ_ERROR_ARCHIVE; indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2; 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); if (totalSize == XZ_SIZE_OVERFLOW || totalSize >= ((UInt64)1 << 63) || pos < totalSize + XZ_STREAM_HEADER_SIZE) return SZ_ERROR_ARCHIVE; pos -= (totalSize + XZ_STREAM_HEADER_SIZE); RINOK(LookInStream_SeekTo(stream, pos)); *startOffset = pos; } { CXzStreamFlags headerFlags; CSecToRead secToRead; SecToRead_CreateVTable(&secToRead); secToRead.realStream = stream; RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt)); return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE; } }
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc) { UInt64 indexSize; Byte buf[XZ_STREAM_FOOTER_SIZE]; if ((*startOffset & 3) != 0 || *startOffset < 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)); if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0) { UInt32 total = 0; *startOffset += 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; 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) break; if (i != 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)) return SZ_ERROR_UNSUPPORTED; if (GetUi32(buf) != CrcCalc(buf + 4, 6)) return SZ_ERROR_ARCHIVE; indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2; *startOffset = -(Int64)(indexSize + XZ_STREAM_FOOTER_SIZE); RINOK(SeekFromCur(stream, startOffset)); 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)) return SZ_ERROR_ARCHIVE; *startOffset = -(Int64)sum; RINOK(SeekFromCur(stream, startOffset)); } { CXzStreamFlags headerFlags; CSecToRead secToRead; SecToRead_CreateVTable(&secToRead); secToRead.realStream = stream; RINOK(Xz_ReadHeader(&headerFlags, &secToRead.s)); return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE; } }