DWORD WINAPI SevenZipGetDefaultPassword(HARC _harc, LPSTR _szPassword, DWORD _dwSize) { g_StdOut.SetLastError(0); LPCWSTR lpPassword; if (_harc == NULL) lpPassword = g_StdOut.GetDefaultPassword(); else { COpenArchive* pOpenArchive = COpenArchive::FindObject(_harc); if (pOpenArchive == NULL) { g_StdOut.SetLastError(ERROR_HARC_ISNOT_OPENED); return -1; } lpPassword = pOpenArchive->GetDefaultPassword(); } if (lpPassword == NULL) { g_StdOut.SetLastError(ERROR_PASSWORD_FILE); return -1; } AString strPassword; if (g_StdOut.GetUnicodeMode()) ::ConvertUnicodeToUTF8(lpPassword, strPassword); else strPassword = ::GetOemString(lpPassword); if ((DWORD)strPassword.Len() >= _dwSize) { g_StdOut.SetLastError(ERROR_INVALID_VALUE); return strPassword.Len() + 1; } ::lstrcpyn(_szPassword, strPassword, _dwSize); return 0; }
static bool FindExt(const char *p, const FString &name) { int dotPos = name.ReverseFind_Dot(); if (dotPos < 0 || dotPos == (int)name.Len() - 1) return false; AString s; for (unsigned pos = dotPos + 1;; pos++) { wchar_t c = name[pos]; if (c == 0) break; if (c >= 0x80) return false; s += (char)MyCharLower_Ascii((char)c); } for (unsigned i = 0; p[i] != 0;) { unsigned j; for (j = i; p[j] != ' '; j++); if (s.Len() == j - i && memcmp(p + i, (const char *)s, s.Len()) == 0) return true; i = j + 1; } return false; }
static void CopyStrLimited(char *dest, const AString &src, unsigned len) { len--; if (src.Len() < len) len = src.Len(); memcpy(dest, src, sizeof(dest[0]) * len); dest[len] = 0; }
static void test_AString() { AString a; a = "abc"; assert(MyStringCompare(&a[0],"abc") == 0); assert(a.Len() == 3); a = GetAnsiString(L"abc"); assert(MyStringCompare(&a[0],"abc") == 0); assert(a.Len() == 3); }
void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT /* codePage */) { dest.Empty(); if (src.IsEmpty()) return; size_t limit = ((size_t)src.Len() + 1) * 2; wchar_t *d = dest.GetBuf((unsigned)limit); size_t len = mbstowcs(d, src, limit); if (len != (size_t)-1) { dest.ReleaseBuf_SetEnd((unsigned)len); return; } { unsigned i; const char *s = (const char *)src; for (i = 0;;) { Byte c = (Byte)s[i]; if (c == 0) break; d[i++] = (wchar_t)c; } d[i] = 0; dest.ReleaseBuf_SetLen(i); } }
bool HasTailSlash(const AString &name, UINT #if defined(_WIN32) && !defined(UNDER_CE) codePage #endif ) { if (name.IsEmpty()) return false; LPCSTR prev = #if defined(_WIN32) && !defined(UNDER_CE) CharPrevExA((WORD)codePage, name, &name[name.Len()], 0); #else (LPCSTR)(name) + (name.Len() - 1); #endif return (*prev == '/'); }
bool CFSFolder::SaveComments() { AString utf; { UString unicode; _comments.SaveToString(unicode); ConvertUnicodeToUTF8(unicode, utf); } if (!utf.IsAscii()) utf.Insert(0, "\xEF\xBB\xBF" "\r\n"); FString path = _path + kDescriptionFileName; // We must set same attrib. COutFile::CreateAlways can fail, if file has another attrib. DWORD attrib = FILE_ATTRIBUTE_NORMAL; { CFileInfo fi; if (fi.Find(path)) attrib = fi.Attrib; } NIO::COutFile file; if (!file.CreateAlways(path, attrib)) return false; UInt32 processed; file.Write(utf, utf.Len(), processed); _commentsAreLoaded = false; return true; }
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) { if (!srcString.IsEmpty()) { UString resultString; const char * path = &srcString[0]; CFStringRef cfpath = CFStringCreateWithCString(NULL,path,kCFStringEncodingUTF8); if (cfpath) { CFMutableStringRef cfpath2 = CFStringCreateMutableCopy(NULL,0,cfpath); CFRelease(cfpath); CFStringNormalize(cfpath2,kCFStringNormalizationFormC); size_t n = CFStringGetLength(cfpath2); for(size_t i = 0 ; i< n ;i++) { UniChar uc = CFStringGetCharacterAtIndex(cfpath2,i); resultString += (wchar_t)uc; // FIXME } CFRelease(cfpath2); return resultString; } } UString resultString; for (int i = 0; i < srcString.Len(); i++) resultString += wchar_t(srcString[i] & 255); return resultString; }
static bool WaitNextLine(const AString &s, unsigned &pos) { for (; pos < s.Len(); pos++) if (s[pos] == 0x0A) return true; return false; }
void MultiByteToUnicodeString2(UString &dest, const AString &src, UINT codePage) { dest.Empty(); if (src.IsEmpty()) return; { /* wchar_t *d = dest.GetBuf(src.Len()); const char *s = (const char *)src; unsigned i; for (i = 0;;) { Byte c = (Byte)s[i]; if (c >= 0x80 || c == 0) break; d[i++] = (wchar_t)c; } if (i != src.Len()) { unsigned len = MultiByteToWideChar(codePage, 0, s + i, src.Len() - i, d + i, src.Len() + 1 - i); if (len == 0) throw 282228; i += len; } d[i] = 0; dest.ReleaseBuf_SetLen(i); */ unsigned len = MultiByteToWideChar(codePage, 0, src, src.Len(), NULL, 0); if (len == 0) { if (GetLastError() != 0) throw 282228; } else { len = MultiByteToWideChar(codePage, 0, src, src.Len(), dest.GetBuf(len), len); if (len == 0) throw 282228; dest.ReleaseBuf_SetEnd(len); } } }
bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs) { pairs.Clear(); unsigned pos = 0; ///////////////////// // read strings for (;;) { if (!SkipSpaces(s, pos)) break; CTextConfigPair pair; unsigned finishPos; AString temp = GetIDString(((const char *)s) + pos, finishPos); if (!ConvertUTF8ToUnicode(temp, pair.ID)) return false; if (finishPos == 0) return false; pos += finishPos; if (!SkipSpaces(s, pos)) return false; if (s[pos] != '=') return false; pos++; if (!SkipSpaces(s, pos)) return false; if (s[pos] != '\"') return false; pos++; AString message; for (;;) { if (pos >= s.Len()) return false; char c = s[pos++]; if (c == '\"') break; if (c == '\\') { c = s[pos++]; switch (c) { case 'n': message += '\n'; break; case 't': message += '\t'; break; case '\\': message += '\\'; break; case '\"': message += '\"'; break; default: message += '\\'; message += c; break; } } else message += c; } if (!ConvertUTF8ToUnicode(message, pair.String)) return false; pairs.Add(pair); } return true; }
void testMaxOSX_stringConvert() { /* 0xE8, // latin small letter e with grave 0xE9, // latin small letter e with acute L'a', 0xE0, // latin small letter a with grave 0x20AC, // euro sign */ struct { char astr [256]; wchar_t ustr [256]; } tab [] = { { // 'a' , 'e with acute' , 'e with grave' , 'a with grave' , 'u with grave' , 'b' , '.' , 't' , 'x' , 't' { 0x61, 0x65, 0xcc, 0x81 , 0x65, 0xcc, 0x80, 0x61, 0xcc, 0x80, 0x75, 0xcc, 0x80, 0x62, 0x2e, 0x74, 0x78, 0x74, 0 }, { 0x61, 0xe9, 0xe8, 0xe0, 0xf9, 0x62, 0x2e, 0x74, 0x78, 0x74, 0 } }, { // 'a' , 'euro sign' , 'b' , '.' , 't' , 'x' , 't' , '\n' { 0x61, 0xe2, 0x82, 0xac, 0x62, 0x2e, 0x74, 0x78, 0x74, 0x0a, 0 }, { 0x61, 0x20AC, 0x62, 0x2e, 0x74, 0x78, 0x74, 0x0a, 0 } }, { { 0 }, { 0 } } }; int i; printf("testMaxOSX_stringConvert : \n"); i = 0; while (tab[i].astr[0]) { printf(" %s\n",tab[i].astr); UString ustr = GetUnicodeString(tab[i].astr); // dumpWStr("1",&ustr[0]); assert(MyStringCompare(&ustr[0],tab[i].ustr) == 0); assert(ustr.Len() == wcslen(tab[i].ustr) ); AString astr = GetAnsiString(ustr); assert(MyStringCompare(&astr[0],tab[i].astr) == 0); assert(astr.Len() == strlen(tab[i].astr) ); i++; } }
void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin)) { CDisableTimerProcessing disableTimerProcessing(*this); CRecordVector<UInt32> indices; GetOperatedItemIndices(indices); if (indices.IsEmpty()) return; CSelectedState state; SaveSelectedState(state); #ifndef UNDER_CE // WM6 / SHFileOperationW doesn't ask user! So we use internal delete if (IsFSFolder() && toRecycleBin) { bool useInternalDelete = false; #ifndef _UNICODE if (!g_IsNT) { CDynamicBuffer<CHAR> buffer; FOR_VECTOR (i, indices) { const AString path = GetSystemString(GetFsPath() + GetItemRelPath(indices[i])); memcpy(buffer.GetCurPtrAndGrow(path.Len() + 1), (const CHAR *)path, (path.Len() + 1) * sizeof(CHAR)); } *buffer.GetCurPtrAndGrow(1) = 0; SHFILEOPSTRUCTA fo; fo.hwnd = GetParent(); fo.wFunc = FO_DELETE; fo.pFrom = (const CHAR *)buffer; fo.pTo = 0; fo.fFlags = 0; if (toRecycleBin) fo.fFlags |= FOF_ALLOWUNDO; // fo.fFlags |= FOF_NOCONFIRMATION; // fo.fFlags |= FOF_NOERRORUI; // fo.fFlags |= FOF_SILENT; // fo.fFlags |= FOF_WANTNUKEWARNING; fo.fAnyOperationsAborted = FALSE; fo.hNameMappings = 0; fo.lpszProgressTitle = 0; /* int res = */ ::SHFileOperationA(&fo); }
UString MultiByteToUnicodeString(const AString &srcString, UINT /* codePage */ ) { #ifdef ENV_HAVE_MBSTOWCS if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) { UString resultString; int numChars = mbstowcs(resultString.GetBuf(srcString.Len()),srcString,srcString.Len()+1); if (numChars >= 0) { resultString.ReleaseBuf_SetEnd(numChars); #if WCHAR_MAX > 0xffff for (int i = numChars; i >= 0; i--) { if (resultString[i] > 0xffff) { wchar_t c = resultString[i] - 0x10000; resultString.Delete(i); wchar_t texts[]= { ((c >> 10) & 0x3ff) + 0xd800, (c & 0x3ff) + 0xdc00 , 0 }; resultString.Insert(i, texts); numChars++; } }
bool ClipboardSetText(HWND owner, const UString &s) { CClipboard clipboard; if (!clipboard.Open(owner)) return false; if (!::EmptyClipboard()) return false; bool res; res = ClipboardSetData(CF_UNICODETEXT, (const wchar_t *)s, (s.Len() + 1) * sizeof(wchar_t)); #ifndef _UNICODE AString a = UnicodeStringToMultiByte(s, CP_ACP); if (ClipboardSetData(CF_TEXT, (const char *)a, (a.Len() + 1) * sizeof(char))) res = true; a = UnicodeStringToMultiByte(s, CP_OEMCP); if (ClipboardSetData(CF_OEMTEXT, (const char *)a, (a.Len() + 1) * sizeof(char))) res = true; #endif return res; }
UString MultiByteToUnicodeString(const AString &srcString, UINT codePage) { if ((global_use_utf16_conversion) && (!srcString.IsEmpty())) { UString resultString; bool bret = ConvertUTF8ToUnicode(srcString,resultString); if (bret) return resultString; } UString resultString; for (int i = 0; i < srcString.Len(); i++) resultString += wchar_t(srcString[i] & 255); return resultString; }
static bool ParseSha1(const CXmlItem &item, const char *name, Byte *digest) { int index = item.FindSubTag(name); if (index < 0) return false; const CXmlItem &checkItem = item.SubItems[index]; const AString style = checkItem.GetPropVal("style"); if (style == "SHA1") { const AString s = checkItem.GetSubString(); if (s.Len() != SHA1_DIGEST_SIZE * 2) return false; for (unsigned i = 0; i < s.Len(); i += 2) { int b0 = HexToByte(s[i]); int b1 = HexToByte(s[i + 1]); if (b0 < 0 || b1 < 0) return false; digest[i / 2] = (Byte)((b0 << 4) | b1); } return true; } return false; }
static bool SkipSpaces(const AString &s, unsigned &pos) { for (; pos < s.Len(); pos++) { char c = s[pos]; if (!IsDelimitChar(c)) { if (c != ';') return true; if (!WaitNextLine(s, pos)) return false; } } return false; }
// ここまでチェック int WINAPI SevenZipPasswordDialog(HWND _hwnd, LPSTR _szBuffer, DWORD _dwSize) { CPasswordDialog dlg(_hwnd, IDS_ENTER_PASSWORD); if (dlg.DoModal() == IDCANCEL) { g_StdOut.SetLastError(ERROR_USER_CANCEL); return -1; } AString strPassword; if (g_StdOut.GetUnicodeMode()) ::ConvertUnicodeToUTF8(dlg.GetPassword(), strPassword); else strPassword = ::GetOemString(dlg.GetPassword()); ::lstrcpynA(_szBuffer, strPassword, _dwSize); return g_StdOut.SetLastError((DWORD)strPassword.Len() < _dwSize ? 0 : ERROR_INVALID_VALUE); }
bool CExtraSubBlock::ExtractInfoZipUnicodePath(AString &name, AString &res) const { res.Empty(); if (ID != NFileHeader::NExtraID::kInfoZipUnicodePath || (UInt32)Data.Size() < 5 || *(const Byte *)Data < 1 || GetUi32((const Byte *)Data + 1) != CrcCalc(name, name.Len())) return false; int size = (int)Data.Size() - sizeof(short) * 2 - sizeof(Byte); if (size > 0) { char *p = res.GetBuffer(size + 1); memcpy(p, (const Byte *)Data + sizeof(short) * 2 + sizeof(Byte), size); p[size] = '\0'; res.ReleaseBuffer(); } return true; }
static UInt64 ParseTime(const CXmlItem &item, const char *name) { const AString s = item.GetSubStringForTag(name); if (s.Len() < 20) return 0; const char *p = s; if (p[ 4] != '-' || p[ 7] != '-' || p[10] != 'T' || p[13] != ':' || p[16] != ':' || p[19] != 'Z') return 0; UInt32 year, month, day, hour, min, sec; PARSE_NUM(4, year) PARSE_NUM(2, month) PARSE_NUM(2, day) PARSE_NUM(2, hour) PARSE_NUM(2, min) PARSE_NUM(2, sec) UInt64 numSecs; if (!NTime::GetSecondsSince1601(year, month, day, hour, min, sec, numSecs)) return 0; return numSecs * 10000000; }
void my_windows_split_path(const AString &p_path, AString &dir , AString &base) { int pos = p_path.ReverseFind('/'); if (pos == -1) { // no separator dir = "."; if (p_path.IsEmpty()) base = "."; else base = p_path; } else if ((pos+1) < p_path.Len()) { // true separator base = p_path.Ptr(pos+1); while ((pos >= 1) && (p_path[pos-1] == '/')) pos--; if (pos == 0) dir = "/"; else dir = p_path.Left(pos); } else { // separator at the end of the path // pos = p_path.find_last_not_of("/"); pos = -1; int ind = 0; while (p_path[ind]) { if (p_path[ind] != '/') pos = ind; ind++; } if (pos == -1) { base = "/"; dir = "/"; } else { my_windows_split_path(p_path.Left(pos+1),dir,base); } } }
HRESULT CZipDecoder::Decode( DECL_EXTERNAL_CODECS_LOC_VARS CInArchive &archive, const CItemEx &item, ISequentialOutStream *realOutStream, IArchiveExtractCallback *extractCallback, ICompressProgressInfo *compressProgress, #ifndef _7ZIP_ST UInt32 numThreads, #endif Int32 &res) { res = NExtract::NOperationResult::kDataError; CInStreamReleaser inStreamReleaser; bool needCRC = true; bool wzAesMode = false; bool pkAesMode = false; UInt16 methodId = item.Method; if (item.IsEncrypted()) { if (item.IsStrongEncrypted()) { CStrongCryptoExtra f; if (item.CentralExtra.GetStrongCrypto(f)) { pkAesMode = true; } if (!pkAesMode) { res = NExtract::NOperationResult::kUnsupportedMethod; return S_OK; } } if (!pkAesMode && methodId == NFileHeader::NCompressionMethod::kWzAES) { CWzAesExtra aesField; if (item.CentralExtra.GetWzAes(aesField)) { wzAesMode = true; needCRC = aesField.NeedCrc(); } } } COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; outStreamSpec->SetStream(realOutStream); outStreamSpec->Init(needCRC); UInt64 authenticationPos; CMyComPtr<ISequentialInStream> inStream; { UInt64 packSize = item.PackSize; if (wzAesMode) { if (packSize < NCrypto::NWzAes::kMacSize) return S_OK; packSize -= NCrypto::NWzAes::kMacSize; } UInt64 dataPos = item.GetDataPosition(); inStream.Attach(archive.CreateLimitedStream(dataPos, packSize)); authenticationPos = dataPos + packSize; } CMyComPtr<ICompressFilter> cryptoFilter; if (item.IsEncrypted()) { if (wzAesMode) { CWzAesExtra aesField; if (!item.CentralExtra.GetWzAes(aesField)) return S_OK; methodId = aesField.Method; if (!_wzAesDecoder) { _wzAesDecoderSpec = new NCrypto::NWzAes::CDecoder; _wzAesDecoder = _wzAesDecoderSpec; } cryptoFilter = _wzAesDecoder; Byte properties = aesField.Strength; RINOK(_wzAesDecoderSpec->SetDecoderProperties2(&properties, 1)); } else if (pkAesMode) { if (!_pkAesDecoder) { _pkAesDecoderSpec = new NCrypto::NZipStrong::CDecoder; _pkAesDecoder = _pkAesDecoderSpec; } cryptoFilter = _pkAesDecoder; } else { if (!_zipCryptoDecoder) { _zipCryptoDecoderSpec = new NCrypto::NZip::CDecoder; _zipCryptoDecoder = _zipCryptoDecoderSpec; } cryptoFilter = _zipCryptoDecoder; } CMyComPtr<ICryptoSetPassword> cryptoSetPassword; RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword)); if (!getTextPassword) extractCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); if (getTextPassword) { CMyComBSTR password; RINOK(getTextPassword->CryptoGetTextPassword(&password)); AString charPassword; if (password) { if (wzAesMode || pkAesMode) { charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_ACP); /* for (unsigned i = 0;; i++) { wchar_t c = password[i]; if (c == 0) break; if (c >= 0x80) { res = NExtract::NOperationResult::kDataError; return S_OK; } charPassword += (char)c; } */ } else { /* pkzip25 / WinZip / Windows probably use ANSI for some files We use OEM for compatibility with previous versions of 7-Zip? */ charPassword = UnicodeStringToMultiByte((const wchar_t *)password, CP_OEMCP); } } HRESULT result = cryptoSetPassword->CryptoSetPassword( (const Byte *)(const char *)charPassword, charPassword.Len()); if (result != S_OK) return S_OK; } else { RINOK(cryptoSetPassword->CryptoSetPassword(0, 0)); } } unsigned m; for (m = 0; m < methodItems.Size(); m++) if (methodItems[m].ZipMethod == methodId) break; if (m == methodItems.Size()) { CMethodItem mi; mi.ZipMethod = methodId; if (methodId == NFileHeader::NCompressionMethod::kStored) mi.Coder = new NCompress::CCopyCoder; else if (methodId == NFileHeader::NCompressionMethod::kShrunk) mi.Coder = new NCompress::NShrink::CDecoder; else if (methodId == NFileHeader::NCompressionMethod::kImploded) mi.Coder = new NCompress::NImplode::NDecoder::CCoder; else if (methodId == NFileHeader::NCompressionMethod::kLZMA) mi.Coder = new CLzmaDecoder; else if (methodId == NFileHeader::NCompressionMethod::kPPMd) mi.Coder = new NCompress::NPpmdZip::CDecoder(true); else { CMethodId szMethodID; if (methodId == NFileHeader::NCompressionMethod::kBZip2) szMethodID = kMethodId_BZip2; else { if (methodId > 0xFF) { res = NExtract::NOperationResult::kUnsupportedMethod; return S_OK; } szMethodID = kMethodId_ZipBase + (Byte)methodId; } RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS szMethodID, mi.Coder, false)); if (mi.Coder == 0) { res = NExtract::NOperationResult::kUnsupportedMethod; return S_OK; } } m = methodItems.Add(mi); } ICompressCoder *coder = methodItems[m].Coder; { CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; coder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties); if (setDecoderProperties) { Byte properties = (Byte)item.Flags; RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1)); } } #ifndef _7ZIP_ST { CMyComPtr<ICompressSetCoderMt> setCoderMt; coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt); if (setCoderMt) { RINOK(setCoderMt->SetNumberOfThreads(numThreads)); } } #endif { HRESULT result = S_OK; CMyComPtr<ISequentialInStream> inStreamNew; if (item.IsEncrypted()) { if (!filterStream) { filterStreamSpec = new CFilterCoder; filterStream = filterStreamSpec; } filterStreamSpec->Filter = cryptoFilter; if (wzAesMode) { result = _wzAesDecoderSpec->ReadHeader(inStream); } else if (pkAesMode) { result =_pkAesDecoderSpec->ReadHeader(inStream, item.Crc, item.Size); if (result == S_OK) { bool passwOK; result = _pkAesDecoderSpec->CheckPassword(passwOK); if (result == S_OK && !passwOK) result = S_FALSE; } } else { result = _zipCryptoDecoderSpec->ReadHeader(inStream); } if (result == S_OK) { if (pkAesMode) { /* 9.31: The BUG in 9.24-9.30 was fixed. pkAes archives didn't work. We don't need to call CAesCbcCoder::Init() to reset IV for data. */ filterStreamSpec->SetInStream_NoSubFilterInit(inStream); } else { RINOK(filterStreamSpec->SetInStream(inStream)); } inStreamReleaser.FilterCoder = filterStreamSpec; inStreamNew = filterStream; if (wzAesMode) { if (!_wzAesDecoderSpec->CheckPasswordVerifyCode()) result = S_FALSE; } } } else inStreamNew = inStream; if (result == S_OK) result = coder->Code(inStreamNew, outStream, NULL, &item.Size, compressProgress); if (result == S_FALSE) return S_OK; if (result == E_NOTIMPL) { res = NExtract::NOperationResult::kUnsupportedMethod; return S_OK; } RINOK(result); } bool crcOK = true; bool authOk = true; if (needCRC) crcOK = (outStreamSpec->GetCRC() == item.Crc); if (wzAesMode) { inStream.Attach(archive.CreateLimitedStream(authenticationPos, NCrypto::NWzAes::kMacSize)); if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK) authOk = false; } res = ((crcOK && authOk) ? NExtract::NOperationResult::kOK : NExtract::NOperationResult::kCRCError); return S_OK; }
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 bool AddItem(const CXmlItem &item, CObjectVector<CFile> &files, int parent) { if (!item.IsTag) return true; if (item.Name == "file") { CFile file; file.Parent = parent; parent = files.Size(); file.Name = item.GetSubStringForTag("name"); AString type = item.GetSubStringForTag("type"); if (type == "directory") file.IsDir = true; else if (type == "file") file.IsDir = false; else return false; int dataIndex = item.FindSubTag("data"); if (dataIndex >= 0 && !file.IsDir) { file.HasData = true; const CXmlItem &dataItem = item.SubItems[dataIndex]; if (!ParseUInt64(dataItem, "size", file.Size)) return false; if (!ParseUInt64(dataItem, "length", file.PackSize)) return false; if (!ParseUInt64(dataItem, "offset", file.Offset)) return false; file.Sha1IsDefined = ParseSha1(dataItem, "extracted-checksum", file.Sha1); // file.packSha1IsDefined = ParseSha1(dataItem, "archived-checksum", file.packSha1); int encodingIndex = dataItem.FindSubTag("encoding"); if (encodingIndex >= 0) { const CXmlItem &encodingItem = dataItem.SubItems[encodingIndex]; if (encodingItem.IsTag) { AString s = encodingItem.GetPropVal("style"); if (!s.IsEmpty()) { const AString appl = "application/"; if (s.IsPrefixedBy(appl)) { s.DeleteFrontal(appl.Len()); const AString xx = "x-"; if (s.IsPrefixedBy(xx)) { s.DeleteFrontal(xx.Len()); if (s == "gzip") s = METHOD_NAME_ZLIB; } } file.Method = s; } } } } file.CTime = ParseTime(item, "ctime"); file.MTime = ParseTime(item, "mtime"); file.ATime = ParseTime(item, "atime"); { const AString s = item.GetSubStringForTag("mode"); if (s[0] == '0') { const char *end; file.Mode = ConvertOctStringToUInt32(s, &end); file.ModeDefined = (*end == 0); } } file.User = item.GetSubStringForTag("user"); file.Group = item.GetSubStringForTag("group"); files.Add(file); } FOR_VECTOR (i, item.SubItems) if (!AddItem(item.SubItems[i], files, parent)) return false; return true; }