diff --git a/src/filesys.cpp b/src/filesys.cpp index 26cdaba07..733a3b203 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -954,13 +954,22 @@ bool extractZipFile(io::IFileSystem *fs, const char *filename, const std::string const io::IFileList* files_in_zip = opened_zip->getFileList(); for (u32 i = 0; i < files_in_zip->getFileCount(); i++) { - std::string fullpath = destination + DIR_DELIM; - fullpath += files_in_zip->getFullFileName(i).c_str(); - std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath); - if (files_in_zip->isDirectory(i)) continue; // ignore, we create dirs as necessary + const auto &filename = files_in_zip->getFullFileName(i); + std::string fullpath = destination + DIR_DELIM; + fullpath += filename.c_str(); + + fullpath = fs::RemoveRelativePathComponents(fullpath); + if (!fs::PathStartsWith(fullpath, destination)) { + warningstream << "fs::extractZipFile(): refusing to extract file \"" + << filename.c_str() << "\"" << std::endl; + continue; + } + + std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath); + if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir)) return false;