diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index ef552c3c2..a1f10c156 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -537,7 +537,12 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop) selectedOptionalMods = optionalModDialog.getResult(); } for (const auto& result : results) { - auto relpath = FS::PathCombine(result.targetFolder, result.fileName); + auto fileName = result.fileName; +#ifdef Q_OS_WIN + fileName = FS::RemoveInvalidPathChars(fileName); +#endif + auto relpath = FS::PathCombine(result.targetFolder, fileName); + if (!result.required && !selectedOptionalMods.contains(relpath)) { relpath += ".disabled"; } diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index 345883c17..83a28fa2b 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -1,5 +1,6 @@ #include "FlameModIndex.h" +#include "FileSystem.h" #include "Json.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" @@ -138,6 +139,9 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) -> file.version = Json::requireString(obj, "displayName"); file.downloadUrl = Json::ensureString(obj, "downloadUrl"); file.fileName = Json::requireString(obj, "fileName"); +#ifdef Q_OS_WIN + file.fileName = FS::RemoveInvalidPathChars(file.fileName); +#endif ModPlatform::IndexedVersionType::VersionType ver_type; switch (Json::requireInteger(obj, "releaseType")) { diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index a688cea87..3b875103b 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -240,11 +240,15 @@ bool ModrinthCreationTask::createInstance() auto root_modpack_url = QUrl::fromLocalFile(root_modpack_path); for (auto file : m_files) { - auto file_path = FS::PathCombine(root_modpack_path, file.path); + auto fileName = file.path; +#ifdef Q_OS_WIN + fileName = FS::RemoveInvalidPathChars(fileName); +#endif + auto file_path = FS::PathCombine(root_modpack_path, fileName); if (!root_modpack_url.isParentOf(QUrl::fromLocalFile(file_path))) { // This means we somehow got out of the root folder, so abort here to prevent exploits setError(tr("One of the files has a path that leads to an arbitrary location (%1). This is a security risk and isn't allowed.") - .arg(file.path)); + .arg(fileName)); return false; } diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index c1c30ab5f..4671a330d 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -17,6 +17,7 @@ */ #include "ModrinthPackIndex.h" +#include "FileSystem.h" #include "ModrinthAPI.h" #include "Json.h" @@ -226,6 +227,9 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t if (parent.contains("url")) { file.downloadUrl = Json::requireString(parent, "url"); file.fileName = Json::requireString(parent, "filename"); +#ifdef Q_OS_WIN + file.fileName = FS::RemoveInvalidPathChars(file.fileName); +#endif file.is_preferred = Json::requireBoolean(parent, "primary") || (files.count() == 1); auto hash_list = Json::requireObject(parent, "hashes"); diff --git a/launcher/net/HttpMetaCache.cpp b/launcher/net/HttpMetaCache.cpp index f37bc0bf8..648155412 100644 --- a/launcher/net/HttpMetaCache.cpp +++ b/launcher/net/HttpMetaCache.cpp @@ -84,6 +84,9 @@ auto HttpMetaCache::getEntry(QString base, QString resource_path) -> MetaEntryPt auto HttpMetaCache::resolveEntry(QString base, QString resource_path, QString expected_etag) -> MetaEntryPtr { +#ifdef Q_OS_WIN + resource_path = FS::RemoveInvalidPathChars(resource_path); +#endif auto entry = getEntry(base, resource_path); // it's not present? generate a default stale entry if (!entry) { diff --git a/launcher/net/NetRequest.cpp b/launcher/net/NetRequest.cpp index 728c0e077..526fe77a5 100644 --- a/launcher/net/NetRequest.cpp +++ b/launcher/net/NetRequest.cpp @@ -68,7 +68,8 @@ void NetRequest::executeTask() if (getState() == Task::State::AbortedByUser) { qCWarning(logCat) << getUid().toString() << "Attempt to start an aborted Request:" << m_url.toString(); - emitAborted(); + emit aborted(); + emit finished(); return; } @@ -85,10 +86,12 @@ void NetRequest::executeTask() break; case State::Inactive: case State::Failed: - emitFailed(); + emit failed("Failed to initilize sink"); + emit finished(); return; case State::AbortedByUser: - emitAborted(); + emit aborted(); + emit finished(); return; }