Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions 3rdparty/interface/archiveinterface/cliinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,59 @@ bool CliInterface::moveExtractTempFilesToDest(const QList<FileEntry> &files, con
return moveSuccess;
}

void CliInterface::removeExtractedFilesOnFailure(const QString &strTargetPath, const QList<FileEntry> &entries)
{
QList<FileEntry> listToRemove = entries;
if (listToRemove.isEmpty()) {
listToRemove = DataManager::get_instance().archiveData().mapFileEntry.values();
}
if (listToRemove.isEmpty()) {
return;
}

QDir targetDir(strTargetPath);
if (!targetDir.exists()) {
return;
}

QList<QPair<QString, bool> > paths; // path, isDirectory
for (const FileEntry &entry : listToRemove) {
QString relPath = entry.strFullPath;
if (relPath.endsWith(QLatin1Char('/'))) {
relPath.chop(1);
}
if (relPath.isEmpty()) {
continue;
}
paths.append(qMakePair(targetDir.absoluteFilePath(relPath), entry.isDirectory));
}

for (const auto &p : paths) {
const QString &path = p.first;
if (!p.second) { // 文件
QFileInfo fi(path);
if (fi.exists() && fi.isFile() && fi.size() == 0) {
Comment on lines +1130 to +1132
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Deleting all zero-size files on failure may remove legitimately empty files from the archive.

This will delete all zero-sized files in paths, including ones that are intentionally empty and were successfully written before the failure. To avoid removing valid files, consider tracking which files were actually created/modified during the failed extraction (e.g., via a temp name/extension, a process-local list, or a timestamp window) instead of relying solely on size() == 0.

QFile::remove(path);
}
}
}
// 空目录可能有多层,循环直到本轮没有可删的空目录
bool removed;
do {
removed = false;
for (const auto &p : paths) {
if (!p.second) {
continue;
}
QDir d(p.first);
if (d.exists() && d.isEmpty()) {
d.removeRecursively();
removed = true;
}
}
} while (removed);
}

bool CliInterface::handleLongNameExtract(const QList<FileEntry> &files)
{
ExtractionOptions &options = m_extractOptions;
Expand Down Expand Up @@ -1272,6 +1325,7 @@ void CliInterface::readStdout(bool handleAll)
// 第二个判断条件是处理rar的list,当rar文件含有comment信息的时候需要根据空行解析
if (!line.isEmpty() || (m_listEmptyLines && m_workStatus == WT_List)) {
if (!handleLine(QString::fromLocal8Bit(line), m_workStatus)) {
emit signalprogress(100);
killProcess();
return;
}
Expand Down Expand Up @@ -1316,6 +1370,11 @@ void CliInterface::extractProcessFinished(int exitCode, QProcess::ExitStatus exi
m_indexOfListRootEntry = 0;
m_isEmptyArchive = false;

// 解压失败(如分卷加密包输错密码)且为全部解压到目标路径时,清理已生成的 size 为 0 等残留文件
if (0 != exitCode && m_extractOptions.bAllExtract && !m_extractOptions.strTargetPath.isEmpty()) {
removeExtractedFilesOnFailure(m_extractOptions.strTargetPath, m_files);
}

if (!m_extractOptions.bAllExtract && (!(m_extractOptions.strTargetPath.startsWith("/tmp") && m_extractOptions.strTargetPath.contains("/deepin-compressor-") && m_extractOptions.strDestination.isEmpty()))) {
if (0 == exitCode) { // job正常结束
// 提取操作和打开解压列表文件非第一层的文件
Expand Down
7 changes: 7 additions & 0 deletions 3rdparty/interface/archiveinterface/cliinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,13 @@ class CliInterface : public ReadWriteArchiveInterface
*/
bool moveExtractTempFilesToDest(const QList<FileEntry> &files, const ExtractionOptions &options);

/**
* @brief removeExtractedFilesOnFailure 解压失败时清理已生成的文件(如分卷加密包输错密码时产生的 size 为 0 的文件)
* @param strTargetPath 解压目标路径
* @param entries 本次解压涉及的条目列表(可为空,为空时从 ArchiveData 获取全部)
*/
void removeExtractedFilesOnFailure(const QString &strTargetPath, const QList<FileEntry> &entries);

bool handleLongNameExtract(const QList<FileEntry> &files);

private slots:
Expand Down