Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
  }
}