diff --git a/common/game/serialize.cpp b/common/game/serialize.cpp index c3422b3a0..170ff7d04 100644 --- a/common/game/serialize.cpp +++ b/common/game/serialize.cpp @@ -76,6 +76,8 @@ Serialize::Serialize(Tempest::IDevice& fin) : fin(&fin) { } Serialize::~Serialize() { + if(fin!=nullptr) + mz_zip_reader_end(&impl); closeEntry(); if(fout!=nullptr) { mz_zip_writer_finalize_archive(&impl); @@ -148,20 +150,25 @@ bool Serialize::implSetEntry(std::string_view fname) { } uint32_t Serialize::implDirectorySize(std::string_view e) { - // Get and print information about each file in the archive. - uint32_t cnt = 0; - for(mz_uint i = 0; i filename; + filename.reserve(256); + for(mz_uint i=0; ie.size() && std::memcmp(e.data(),stat.m_filename,e.size())==0) { - auto sep = std::strchr(stat.m_filename+e.size(),'/'); - if(sep==nullptr || (sep+1)==(stat.m_filename+len)) - ++cnt; - } + filename.resize(length); + if(mz_zip_reader_get_filename(&impl, i, filename.data(), length)!=length) + throw std::runtime_error("unable to read entry name in game archive"); + std::string_view name(filename.data(), length-1); + if(name.size()<=e.size() || !name.starts_with(e)) + continue; + const auto child = name.substr(e.size()); + const auto separator = child.find('/'); + if(separator==std::string_view::npos || separator+1==child.size()) + ++count; } - return cnt; + return count; } void Serialize::writeBytes(const void* buf, size_t sz) { diff --git a/common/game/serialize.h b/common/game/serialize.h index 0ec3d2af1..584cf88fd 100644 --- a/common/game/serialize.h +++ b/common/game/serialize.h @@ -45,7 +45,7 @@ class Serialize { }; Serialize(Tempest::ODevice& fout); Serialize(Tempest::IDevice& fin); - Serialize(Serialize&&)=default; + Serialize(Serialize&&)=delete; ~Serialize(); uint16_t version() const { return wldVer; }