From d4a611147c0cb5f1aee2704bb915a749f977ee02 Mon Sep 17 00:00:00 2001 From: Hanif Koh Date: Mon, 28 Sep 2026 15:54:48 +0800 Subject: [PATCH] Sanitize the File Name of Model Import Links The model import took the file name from the link as given and only avoided an existing file with a substring match on the folder listing. Reduce the name to a sanitized base name, falling back to untitled.3mf, choose the name with the shared unused-name search, and check it again before the final rename. --- src/slic3r/GUI/Plater.cpp | 78 +++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index bdb8340edc..59b587bc07 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -15681,6 +15681,11 @@ void Plater::import_model_id(wxString download_info) //wxString sError = error.what(); } + // The name comes from the link: reduce it to a plain file name inside the download folder. + filename = from_u8(sanitize_file_basename(into_u8(filename))); + if (filename.empty()) + filename = "untitled.3mf"; + bool download_ok = false; int retry_count = 0; const int max_retries = 3; @@ -15722,51 +15727,28 @@ void Plater::import_model_id(wxString download_info) msg = _L("Preparing 3MF file..."); - //gets the number of files with the same name - std::vector vecFiles; - bool is_already_exist = false; - - target_path = fs::path(wxGetApp().app_config->get("download_path")); - try - { - vecFiles.clear(); - wxString extension = fs::path(filename.wx_str()).extension().c_str(); - - - //check file suffix - if (!extension.Contains(".3mf")) { - msg = _L("Download failed; unknown file format."); - return; - } - - auto name = filename.substr(0, filename.length() - extension.length() - 1); - - for (const auto& iter : boost::filesystem::directory_iterator(target_path)) - { - if (boost::filesystem::is_directory(iter.path())) - continue; - - wxString sFile = iter.path().filename().string().c_str(); - if (strstr(sFile.c_str(), name.c_str()) != NULL) { - vecFiles.push_back(sFile); - } - - if (sFile == filename) is_already_exist = true; - } - } - catch (const std::exception&) - { - //wxString sError = error.what(); + //check file suffix + wxString extension = fs::path(filename.wx_str()).extension().c_str(); + if (!extension.Contains(".3mf")) { + msg = _L("Download failed; unknown file format."); + return; } - //update filename - if (is_already_exist && vecFiles.size() >= 1) { - wxString extension = fs::path(filename.wx_str()).extension().c_str(); - wxString name = filename.substr(0, filename.length() - extension.length()); - filename = wxString::Format("%s(%d)%s", name, vecFiles.size() + 1, extension).ToStdString(); + //never replace an existing file + std::string unused_filename; + try { + if (!find_unused_filename(target_path, into_u8(filename), {}, unused_filename)) + unused_filename.clear(); + } catch (const std::exception&) { + unused_filename.clear(); } + if (unused_filename.empty()) { + msg = _L("Importing to Orca Slicer failed. Please download the file and manually import it."); + return; + } + filename = from_u8(unused_filename); msg = _L("Downloading project..."); @@ -15778,10 +15760,6 @@ void Plater::import_model_id(wxString download_info) boost::uuids::uuid uuid = boost::uuids::random_generator()(); std::string unique = to_string(uuid).substr(0, 6); - if (filename.empty()) { - filename = "untitled.3mf"; - } - //target_path /= (boost::format("%1%_%2%.3mf") % filename % unique).str(); target_path /= fs::path(filename.wc_str()); @@ -15830,10 +15808,20 @@ void Plater::import_model_id(wxString download_info) cont = false; } }) - .on_complete([&cont, &download_ok, tmp_path, target_path](std::string body, unsigned /* http_status */) { + .on_complete([&cont, &download_ok, &msg, tmp_path, &target_path](std::string body, unsigned /* http_status */) { fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc); file.write(body.c_str(), body.size()); file.close(); + // Another file may have taken the name while downloading. + std::string unused_filename; + if (!find_unused_filename(target_path.parent_path(), target_path.filename().string(), {}, unused_filename)) { + boost::system::error_code ec; + fs::remove(tmp_path, ec); + msg = _L("Importing to Orca Slicer failed. Please download the file and manually import it."); + cont = false; + return; + } + target_path = target_path.parent_path() / unused_filename; fs::rename(tmp_path, target_path); cont = false; download_ok = true;