aboutsummaryrefslogtreecommitdiff
path: root/launcher/MMCZip.cpp
diff options
context:
space:
mode:
authorTrial97 <alexandru.tripon97@gmail.com>2023-05-31 20:12:12 +0300
committerTrial97 <alexandru.tripon97@gmail.com>2023-05-31 20:12:12 +0300
commit29c3dc40ef7f5b1fce5ab5970a39613d0f7f5089 (patch)
treece92f8a86d08531879105a16194a14391c0ae2ea /launcher/MMCZip.cpp
parente8ee4497f77a571b305a48b70f84c8729b800859 (diff)
parent954d4d701a136e79c25b58f9680d26a555a6e6fe (diff)
downloadPrismLauncher-29c3dc40ef7f5b1fce5ab5970a39613d0f7f5089.tar.gz
PrismLauncher-29c3dc40ef7f5b1fce5ab5970a39613d0f7f5089.tar.bz2
PrismLauncher-29c3dc40ef7f5b1fce5ab5970a39613d0f7f5089.zip
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into logdir
Diffstat (limited to 'launcher/MMCZip.cpp')
-rw-r--r--launcher/MMCZip.cpp76
1 files changed, 45 insertions, 31 deletions
diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp
index f6600343..1a336375 100644
--- a/launcher/MMCZip.cpp
+++ b/launcher/MMCZip.cpp
@@ -94,20 +94,28 @@ bool MMCZip::mergeZipFiles(QuaZip *into, QFileInfo from, QSet<QString> &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) {
+ if (e.isSymLink()) {
+ srcPath = e.symLinkTarget();
+ } else {
+ 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());
@@ -116,7 +124,7 @@ bool MMCZip::compressDirFiles(QString fileCompressed, QString dir, QFileInfoList
return false;
}
- auto result = compressDirFiles(&zip, dir, files);
+ auto result = compressDirFiles(&zip, dir, files, followSymlinks);
zip.close();
if(zip.getZipError()!=0) {
@@ -275,7 +283,8 @@ bool MMCZip::findFilesInZip(QuaZip * zip, const QString & what, QStringList & re
// ours
std::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QString &target)
{
- QDir directory(target);
+ auto target_top_dir = QUrl::fromLocalFile(target);
+
QStringList extracted;
qDebug() << "Extracting subdir" << subdir << "from" << zip->getZipName() << "to" << target;
@@ -294,48 +303,53 @@ std::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & su
return std::nullopt;
}
- do
- {
- QString name = zip->getCurrentFileName();
- if(!name.startsWith(subdir))
- {
+ do {
+ QString file_name = zip->getCurrentFileName();
+ if (!file_name.startsWith(subdir))
continue;
- }
- name.remove(0, subdir.size());
- auto original_name = name;
+ auto relative_file_name = QDir::fromNativeSeparators(file_name.remove(0, subdir.size()));
+ auto original_name = relative_file_name;
+
+ // Fix subdirs/files ending with a / getting transformed into absolute paths
+ if (relative_file_name.startsWith('/'))
+ relative_file_name = relative_file_name.mid(1);
// Fix weird "folders with a single file get squashed" thing
- QString path;
- if(name.contains('/') && !name.endsWith('/')){
- path = name.section('/', 0, -2) + "/";
- FS::ensureFolderPathExists(FS::PathCombine(target, path));
+ QString sub_path;
+ if (relative_file_name.contains('/') && !relative_file_name.endsWith('/')) {
+ sub_path = relative_file_name.section('/', 0, -2) + '/';
+ FS::ensureFolderPathExists(FS::PathCombine(target, sub_path));
- name = name.split('/').last();
+ relative_file_name = relative_file_name.split('/').last();
}
- QString absFilePath;
- if(name.isEmpty())
- {
- absFilePath = directory.absoluteFilePath(name) + "/";
+ QString target_file_path;
+ if (relative_file_name.isEmpty()) {
+ target_file_path = target + '/';
+ } else {
+ target_file_path = FS::PathCombine(target_top_dir.toLocalFile(), sub_path, relative_file_name);
+ if (relative_file_name.endsWith('/') && !target_file_path.endsWith('/'))
+ target_file_path += '/';
}
- else
- {
- absFilePath = directory.absoluteFilePath(path + name);
+
+ if (!target_top_dir.isParentOf(QUrl::fromLocalFile(target_file_path))) {
+ qWarning() << "Extracting" << relative_file_name << "was cancelled, because it was effectively outside of the target path" << target;
+ return std::nullopt;
}
- if (!JlCompress::extractFile(zip, "", absFilePath))
- {
- qWarning() << "Failed to extract file" << original_name << "to" << absFilePath;
+ if (!JlCompress::extractFile(zip, "", target_file_path)) {
+ qWarning() << "Failed to extract file" << original_name << "to" << target_file_path;
JlCompress::removeFile(extracted);
return std::nullopt;
}
- extracted.append(absFilePath);
- QFile::setPermissions(absFilePath, QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser);
+ extracted.append(target_file_path);
+ QFile::setPermissions(target_file_path, QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser);
- qDebug() << "Extracted file" << name << "to" << absFilePath;
+ qDebug() << "Extracted file" << relative_file_name << "to" << target_file_path;
} while (zip->goToNextFile());
+
return extracted;
}