Fix logic in ZipFileReader file listing

This commit is contained in:
Henrik Rydgård 2023-05-01 23:20:38 +02:00
parent 8bb2643459
commit 35aff7eaf9
2 changed files with 16 additions and 9 deletions

View File

@ -132,26 +132,29 @@ bool ZipFileReader::GetFileListing(const char *orig_path, std::vector<File::File
void ZipFileReader::GetZipListings(const char *path, std::set<std::string> &files, std::set<std::string> &directories) { void ZipFileReader::GetZipListings(const char *path, std::set<std::string> &files, std::set<std::string> &directories) {
size_t pathlen = strlen(path); size_t pathlen = strlen(path);
if (path[pathlen - 1] == '/') if (pathlen == 1 && path[0] == '/') {
pathlen--; // Root. We simply use a zero length string.
pathlen = 0;
}
std::lock_guard<std::mutex> guard(lock_); std::lock_guard<std::mutex> guard(lock_);
int numFiles = zip_get_num_files(zip_file_); int numFiles = zip_get_num_files(zip_file_);
for (int i = 0; i < numFiles; i++) { for (int i = 0; i < numFiles; i++) {
const char* name = zip_get_name(zip_file_, i, 0); const char* name = zip_get_name(zip_file_, i, 0);
if (!name) if (!name)
continue; continue; // shouldn't happen, I think
if (!memcmp(name, path, pathlen)) { if (!memcmp(name, path, pathlen)) {
// The prefix is right. Let's see if this is a file or path.
const char *slashPos = strchr(name + pathlen + 1, '/'); const char *slashPos = strchr(name + pathlen + 1, '/');
if (slashPos != 0) { if (slashPos != 0) {
// A directory. // A directory. Let's pick off the only part we care about.
std::string dirName = std::string(name + pathlen + 1, slashPos - (name + pathlen + 1)); int offset = pathlen;
std::string dirName = std::string(name + offset, slashPos - (name + offset));
directories.insert(dirName); directories.insert(dirName);
} else if (name[pathlen] == '/') { } else {
const char *fn = name + pathlen + 1; // It's a file.
const char *fn = name + pathlen;
files.insert(std::string(fn)); files.insert(std::string(fn));
} // else, it was a file with the same prefix as the path. like langregion.ini next to lang/. }
} }
} }
} }

View File

@ -61,6 +61,10 @@ inline bool endsWithNoCase(const std::string &str, const std::string &what) {
return strncasecmp(str.c_str() + offset, what.c_str(), what.size()) == 0; return strncasecmp(str.c_str() + offset, what.c_str(), what.size()) == 0;
} }
inline bool equalsNoCase(const std::string &str, const char *what) {
return strcasecmp(str.c_str(), what) == 0;
}
void DataToHexString(const uint8_t *data, size_t size, std::string *output); void DataToHexString(const uint8_t *data, size_t size, std::string *output);
void DataToHexString(int indent, uint32_t startAddr, const uint8_t* data, size_t size, std::string* output); void DataToHexString(int indent, uint32_t startAddr, const uint8_t* data, size_t size, std::string* output);