fix+refactor: fix fail to import modpacks and clean up a bit

QDir::cleanPath called by FS::PathCombine removes the trailing '/'...

Signed-off-by: flow <flowlnlnln@gmail.com>
This commit is contained in:
flow 2023-02-24 20:08:29 -03:00
parent 8ce8055aeb
commit fda9ca1e34
No known key found for this signature in database
GPG Key ID: 8D0F221F0A59F469

View File

@ -275,7 +275,7 @@ bool MMCZip::findFilesInZip(QuaZip * zip, const QString & what, QStringList & re
// ours // ours
std::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QString &target) std::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & subdir, const QString &target)
{ {
auto absDirectoryUrl = QUrl::fromLocalFile(target); auto target_top_dir = QUrl::fromLocalFile(target);
QStringList extracted; QStringList extracted;
@ -295,58 +295,53 @@ std::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString & su
return std::nullopt; return std::nullopt;
} }
do do {
{ QString file_name = zip->getCurrentFileName();
QString name = zip->getCurrentFileName(); if (!file_name.startsWith(subdir))
if(!name.startsWith(subdir))
{
continue; continue;
}
name.remove(0, subdir.size()); auto relative_file_name = QDir::fromNativeSeparators(file_name.remove(0, subdir.size()));
auto original_name = name; auto original_name = relative_file_name;
// Fix subdirs/files ending with a / getting transformed into absolute paths // Fix subdirs/files ending with a / getting transformed into absolute paths
if(name.startsWith('/')){ if (relative_file_name.startsWith('/'))
name = name.mid(1); relative_file_name = relative_file_name.mid(1);
}
// Fix weird "folders with a single file get squashed" thing // Fix weird "folders with a single file get squashed" thing
QString path; QString sub_path;
if(name.contains('/') && !name.endsWith('/')){ if (relative_file_name.contains('/') && !relative_file_name.endsWith('/')) {
path = name.section('/', 0, -2) + "/"; sub_path = relative_file_name.section('/', 0, -2) + '/';
FS::ensureFolderPathExists(FS::PathCombine(target, path)); FS::ensureFolderPathExists(FS::PathCombine(target, sub_path));
name = name.split('/').last(); relative_file_name = relative_file_name.split('/').last();
} }
QString absFilePath; QString target_file_path;
if(name.isEmpty()) if (relative_file_name.isEmpty()) {
{ target_file_path = target + '/';
absFilePath = FS::PathCombine(target, "/"); // FIXME this seems weird } else {
} target_file_path = FS::PathCombine(target_top_dir.path(), sub_path, relative_file_name);
else if (relative_file_name.endsWith('/') && !target_file_path.endsWith('/'))
{ target_file_path += '/';
absFilePath = FS::PathCombine(target, path + name);
} }
if (!absDirectoryUrl.isParentOf(QUrl::fromLocalFile(absFilePath))) { if (!target_top_dir.isParentOf(QUrl::fromLocalFile(target_file_path))) {
qWarning() << "Extracting" << name << "was cancelled, because it was effectively outside of the target path" << target; qWarning() << "Extracting" << relative_file_name << "was cancelled, because it was effectively outside of the target path" << target;
return std::nullopt; return std::nullopt;
} }
if (!JlCompress::extractFile(zip, "", absFilePath)) if (!JlCompress::extractFile(zip, "", target_file_path)) {
{ qWarning() << "Failed to extract file" << original_name << "to" << target_file_path;
qWarning() << "Failed to extract file" << original_name << "to" << absFilePath;
JlCompress::removeFile(extracted); JlCompress::removeFile(extracted);
return std::nullopt; return std::nullopt;
} }
extracted.append(absFilePath); extracted.append(target_file_path);
QFile::setPermissions(absFilePath, QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser); 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()); } while (zip->goToNextFile());
return extracted; return extracted;
} }