From c9105e525e175ee8181ab0a6998d0e21526f116d Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 8 Feb 2023 18:52:50 -0700 Subject: [PATCH] fix: follow symlinks when exporting Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/FileSystem.h | 2 +- launcher/MMCZip.cpp | 9 ++++++--- launcher/MMCZip.h | 6 ++++-- launcher/ui/dialogs/ExportInstanceDialog.cpp | 5 ++++- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index d79096e6..782a2f40 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -144,7 +144,7 @@ class ExternalLinkFileProcess : public QThread { Q_OBJECT public: ExternalLinkFileProcess(QString server, bool useHardLinks, QObject* parent = nullptr) - : QThread(parent), m_server(server), m_useHardLinks(useHardLinks) + : QThread(parent), m_useHardLinks(useHardLinks), m_server(server) {} void run() override diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp index 1eda43fe..b4b663c1 100644 --- a/launcher/MMCZip.cpp +++ b/launcher/MMCZip.cpp @@ -94,20 +94,23 @@ bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet &containe return true; } -bool MMCZip::compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files) +bool MMCZip::compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, bool followSymlinks) { QDir directory(dir); if (!directory.exists()) return false; for (auto e : files) { auto filePath = directory.relativeFilePath(e.absoluteFilePath()); - if( !JlCompress::compressFile(zip, e.absoluteFilePath(), filePath)) return false; + auto srcPath = e.absoluteFilePath(); + if (followSymlinks) + srcPath = e.canonicalFilePath(); + if( !JlCompress::compressFile(zip, srcPath, filePath)) return false; } return true; } -bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files) +bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks) { QuaZip zip(fileCompressed); QDir().mkpath(QFileInfo(fileCompressed).absolutePath()); diff --git a/launcher/MMCZip.h b/launcher/MMCZip.h index 81f9cb90..2a78f830 100644 --- a/launcher/MMCZip.h +++ b/launcher/MMCZip.h @@ -59,18 +59,20 @@ namespace MMCZip * \param zip target archive * \param dir directory that will be compressed (to compress with relative paths) * \param files list of files to compress + * \param followSymlinks should follow symlinks when compressing file data * \return true for success or false for failure */ - bool compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files); + bool compressDirFiles(QuaZip *zip, QString dir, QFileInfoList files, bool followSymlinks = false); /** * Compress directory, by providing a list of files to compress * \param fileCompressed target archive file * \param dir directory that will be compressed (to compress with relative paths) * \param files list of files to compress + * \param followSymlinks should follow symlinks when compressing file data * \return true for success or false for failure */ - bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files); + bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks = false); /** * take a source jar, add mods to it, resulting in target jar diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index f13e36e8..07ec3c70 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -45,6 +45,8 @@ #include #include #include +#include + #include "StringUtils.h" #include "SeparatorPrefixTree.h" #include "Application.h" @@ -429,7 +431,8 @@ bool ExportInstanceDialog::doExport() QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); return false; } - if (!MMCZip::compressDirFiles(output, m_instance->instanceRoot(), files)) + + if (!MMCZip::compressDirFiles(output, m_instance->instanceRoot(), files, true)) { QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); return false;