diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 9ba542d878..0b8459bf6e 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -324,7 +324,7 @@ bool PresetUpdater::priv::extract_file(const fs::path &source_path, const fs::pa { bool res = true; std::string file_path = source_path.string(); - std::string parent_path = (!dest_path.empty() ? dest_path : source_path.parent_path()).string(); + fs::path parent_path = !dest_path.empty() ? dest_path : source_path.parent_path(); mz_zip_archive archive; mz_zip_zero_struct(&archive); @@ -335,6 +335,7 @@ bool PresetUpdater::priv::extract_file(const fs::path &source_path, const fs::pa } mz_uint num_entries = mz_zip_reader_get_num_files(&archive); + fs::path base_path = parent_path.lexically_normal(); mz_zip_archive_file_stat stat; // we first loop the entries to read from the archive the .amf file only, in order to extract the version from it @@ -342,30 +343,48 @@ bool PresetUpdater::priv::extract_file(const fs::path &source_path, const fs::pa { if (mz_zip_reader_file_stat(&archive, i, &stat)) { - std::string dest_file = parent_path+"/"+stat.m_filename; - if (stat.m_is_directory) { - fs::path dest_path(dest_file); - if (!fs::exists(dest_path)) - fs::create_directories(dest_path); - continue; + fs::path full_dest = (base_path / stat.m_filename).lexically_normal(); + // Reject paths that escape base (e.g. ".." in zip entry) + std::string rel_str = full_dest.lexically_relative(base_path).generic_string(); + if (rel_str.empty() || rel_str.find("..") == 0) { + BOOST_LOG_TRIVIAL(warning) << "[Orca Updater]Unzip: skip invalid path "<