HRESULT CInArchive::ReadLocalItemAfterCdItemFull(CItemEx &item) { if (item.FromLocal) return S_OK; try { RINOK(ReadLocalItemAfterCdItem(item)); if (item.HasDescriptor()) { RINOK(Seek(ArcInfo.Base + item.GetDataPosition() + item.PackSize)); if (ReadUInt32() != NSignature::kDataDescriptor) return S_FALSE; UInt32 crc = ReadUInt32(); UInt64 packSize, unpackSize; /* if (IsZip64) { packSize = ReadUInt64(); unpackSize = ReadUInt64(); } else */ { packSize = ReadUInt32(); unpackSize = ReadUInt32(); } if (crc != item.Crc || item.PackSize != packSize || item.Size != unpackSize) return S_FALSE; } } catch(...) { return S_FALSE; } return S_OK; }
static bool AreItemsEqual(const CItemEx &localItem, const CItemEx &cdItem) { if (!FlagsAreSame(cdItem, localItem)) return false; if (!localItem.HasDescriptor()) { if (cdItem.Crc != localItem.Crc || cdItem.PackSize != localItem.PackSize || cdItem.Size != localItem.Size) return false; } /* pkzip 2.50 creates incorrect archives. It uses - WIN encoding for name in local header - OEM encoding for name in central header We don't support these strange items. */ /* if (cdItem.Name.Len() != localItem.Name.Len()) return false; */ if (cdItem.Name != localItem.Name) return false; return true; }
HRESULT CInArchive::ReadLocals( CObjectVector<CItemEx> &items, CProgressVirt *progress) { items.Clear(); while (m_Signature == NSignature::kLocalFileHeader) { CItemEx item; item.LocalHeaderPos = m_Position - 4 - ArcInfo.MarkerPos; // we write ralative LocalHeaderPos here. Later we can correct it to real Base. try { ReadLocalItem(item); item.FromLocal = true; if (item.HasDescriptor()) ReadLocalItemDescriptor(item); else { RINOK(IncreaseRealPosition(item.PackSize)); } items.Add(item); m_Signature = ReadUInt32(); } catch (CUnexpectEnd &) { if (items.IsEmpty() || items.Size() == 1 && IsStrangeItem(items[0])) return S_FALSE; throw; } if (progress && items.Size() % 1 == 0) RINOK(progress->SetCompletedLocal(items.Size(), item.LocalHeaderPos)); } if (items.Size() == 1 && m_Signature != NSignature::kCentralFileHeader) if (IsStrangeItem(items[0])) return S_FALSE; return S_OK; }