Skip to content

Commit d3d3f4a

Browse files
committed
fix: Compressed file seek detection
Compressed file seek detection Bug: https://pms.uniontech.com/bug-view-278613.html Log: Compressed file seek detection
1 parent b89d364 commit d3d3f4a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+13307
-13676
lines changed

3rdparty/interface/archiveinterface/cliinterface.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <QUrl>
4040
#include <QScopedPointer>
4141
#include <QTemporaryDir>
42+
#include <QTimer>
4243

4344
#include "common.h"
4445
#include <linux/limits.h>
@@ -68,6 +69,15 @@ PluginFinishType CliInterface::list()
6869
m_setHasHandlesDirs.clear();
6970

7071
m_workStatus = WT_List;
72+
//是否支持seek
73+
if(!m_common->isSupportSeek(m_strArchiveName)) {
74+
QTimer::singleShot(1000, this, [=]() {
75+
m_eErrorType = ET_FileSeekError;
76+
emit signalprogress(100);
77+
emit signalFinished(PFT_Error);
78+
});
79+
return PFT_Error;
80+
}
7181

7282
bool ret = false;
7383

@@ -85,6 +95,15 @@ PluginFinishType CliInterface::testArchive()
8595

8696
PluginFinishType CliInterface::extractFiles(const QList<FileEntry> &files, const ExtractionOptions &options)
8797
{
98+
//是否支持seek
99+
if(!m_common->isSupportSeek(m_strArchiveName)) {
100+
QTimer::singleShot(1000, this, [=]() {
101+
m_eErrorType = ET_FileSeekError;
102+
emit signalprogress(100);
103+
emit signalFinished(PFT_Error);
104+
});
105+
return PFT_Nomral;
106+
}
88107
bool bDlnfs = m_common->isSubpathOfDlnfs(options.strTargetPath);
89108
setProperty("dlnfs", bDlnfs);
90109
ArchiveData arcData = DataManager::get_instance().archiveData();
@@ -298,6 +317,15 @@ bool CliInterface::doKill()
298317

299318
PluginFinishType CliInterface::addFiles(const QList<FileEntry> &files, const CompressOptions &options)
300319
{
320+
//是否支持seek
321+
if(!files.isEmpty() && !m_common->isSupportSeek(m_strArchiveName)) {
322+
QTimer::singleShot(1000, this, [=]() {
323+
m_eErrorType = ET_FileSeekError;
324+
emit signalprogress(100);
325+
emit signalFinished(PFT_Error);
326+
});
327+
return PFT_Nomral;
328+
}
301329
setPassword(QString());
302330
m_workStatus = WT_Add;
303331
m_files = files;

3rdparty/interface/common.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <QFileInfo>
1515
#include <QDir>
1616
#include <linux/limits.h>
17+
#include <QTemporaryFile>
1718

1819
#include <KEncodingProber>
1920
#include "chardet.h"
@@ -425,6 +426,44 @@ bool Common::isSubpathOfDlnfs(const QString &path)
425426
});
426427
}
427428

429+
bool Common::isSupportSeek(QString sFileName)
430+
{
431+
QFileInfo info(sFileName);
432+
if(info.exists()) {
433+
QFile file(sFileName);
434+
if(file.open(QIODevice::ReadOnly)) {
435+
if (file.seek(0)) {
436+
file.close();
437+
return true; // 支持 seek
438+
}
439+
}
440+
file.close();
441+
} else {
442+
// 指定临时文件的目录
443+
QString tempDir = info.absoluteDir().path(); // 替换为你的目录路径
444+
QString fileTemplate = tempDir + "/tempfile_XXXXXX"; // 文件名模板
445+
// 创建 QTemporaryFile
446+
QTemporaryFile tempFile(fileTemplate);
447+
tempFile.setAutoRemove(true);
448+
// 尝试打开临时文件
449+
if (tempFile.open()) {
450+
tempFile.write("test\n");
451+
tempFile.flush();
452+
}
453+
tempFile.close();
454+
QString sFileName = tempFile.fileName();
455+
QFile file(sFileName);
456+
if(file.open(QIODevice::ReadOnly)) {
457+
if (file.seek(0)) {
458+
file.close();
459+
return true; // 支持 seek
460+
}
461+
}
462+
file.close();
463+
}
464+
return false;
465+
}
466+
428467
bool Common::findDlnfsPath(const QString &target, Compare func)
429468
{
430469
Q_ASSERT(func);

3rdparty/interface/common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ class Common: public QObject
4141
QString handleLongNameforPath(const QString &strFilePath, const QString &entryName, QMap<QString, int> &mapLongDirName, QMap<QString, int> &mapRealDirValue);
4242
//当前文件系统是否支持长文件
4343
bool isSubpathOfDlnfs(const QString &path);
44+
/**
45+
* @brief isSupportSeek 是否支持seek操作
46+
* @param sFileName 文件名
47+
*/
48+
bool isSupportSeek(QString sFileName);
4449
private:
4550
//通过mount对应方法判断文件系统是否支持长文件
4651
bool findDlnfsPath(const QString &target, Compare func);

3rdparty/interface/commonstruct.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ enum ErrorType {
3939

4040
ET_UserCancelOpertion, // 用户取消操作
4141
ET_ExistVolume, // 分卷已存在
42+
ET_FileSeekError, // 文件不支持seek
43+
4244
};
4345

4446
//加密类型

3rdparty/libarchive/libarchive/libarchiveplugin.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ PluginFinishType LibarchivePlugin::list()
6969
QString fileName = fInfo.fileName();
7070
//因为tar.bz2、tar.lzma、tar.Z直接list时间较长,所以先用7z解压再list处理
7171
if (fileName.endsWith(".tar.bz2") || fileName.endsWith(".tar.lzma") || fileName.endsWith(".tar.Z")) {
72+
//是否支持seek
73+
if(!m_common->isSupportSeek(m_strArchiveName)) {
74+
m_eErrorType = ET_FileSeekError;
75+
return PFT_Error;
76+
}
7277
// 设置解压临时路径
7378
QString strProcessID = QString::number(QCoreApplication::applicationPid()); // 获取应用进程号
7479
QString tempFilePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation)

3rdparty/libzipplugin/libzipplugin.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ PluginFinishType LibzipPlugin::list()
8383
int errcode = 0;
8484
zip_error_t err;
8585

86+
//是否支持seek
87+
if(!m_common->isSupportSeek(m_strArchiveName)) {
88+
m_eErrorType = ET_FileSeekError;
89+
return PFT_Error;
90+
}
8691
// 打开压缩包文件
8792
zip_t *archive = zip_open(QFile::encodeName(m_strArchiveName).constData(), ZIP_RDONLY, &errcode); // 打开压缩包文件
8893
zip_error_init_with_code(&err, errcode);
@@ -135,7 +140,11 @@ PluginFinishType LibzipPlugin::extractFiles(const QList<FileEntry> &files, const
135140
m_mapRealDirValue.clear();
136141
// m_bHandleCurEntry = false; //false:提取使用选中文件及子文件 true:提取使用选中文件
137142
zip_error_t err;
138-
143+
//是否支持seek
144+
if(!m_common->isSupportSeek(m_strArchiveName)) {
145+
m_eErrorType = ET_FileSeekError;
146+
return PFT_Error;
147+
}
139148
// 打开压缩包
140149
zip_t *archive = zip_open(QFile::encodeName(m_strArchiveName).constData(), ZIP_RDONLY, &errcode);
141150
zip_error_init_with_code(&err, errcode);

src/source/common/uistruct.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ enum ErrorInfo {
181181
EI_InsufficientDiskSpace, // 磁盘空间不足
182182
EI_ArchiveNoData, // 压缩包无数据
183183
EI_ExistVolume, // 分卷已存在
184+
EI_FileSeekError, // seek失败
184185
};
185186

186187
// 启动应用的方式

src/source/mainwindow.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,6 +1617,10 @@ void MainWindow::handleJobErrorFinished(ArchiveJob::JobType eJobType, ErrorType
16171617
case ET_ExistVolume:
16181618
showErrorMessage(FI_Compress, EI_ExistVolume, true);
16191619
break;
1620+
// ftp目录不支持seek操作
1621+
case ET_FileSeekError:
1622+
showErrorMessage(FI_Compress, EI_FileSeekError, true);
1623+
break;
16201624
default: {
16211625
showErrorMessage(FI_Compress, EI_CreatArchiveFailed, true);
16221626
break;
@@ -1672,6 +1676,10 @@ void MainWindow::handleJobErrorFinished(ArchiveJob::JobType eJobType, ErrorType
16721676
case ET_WrongPassword:
16731677
showErrorMessage(FI_Load, EI_WrongPassword);
16741678
break;
1679+
// ftp目录不支持seek操作
1680+
case ET_FileSeekError:
1681+
showErrorMessage(FI_Load, EI_FileSeekError);
1682+
break;
16751683
default:
16761684
showErrorMessage(FI_Load, EI_ArchiveDamaged);
16771685
break;
@@ -1758,6 +1766,10 @@ void MainWindow::handleJobErrorFinished(ArchiveJob::JobType eJobType, ErrorType
17581766
!(StartupType::ST_ExtractHere == m_eStartupType || StartupType::ST_Extractto == m_eStartupType));
17591767
break;
17601768
}
1769+
// ftp目录不支持seek操作
1770+
case ET_FileSeekError:
1771+
showErrorMessage(FI_Uncompress, EI_FileSeekError);
1772+
break;
17611773
case ET_PluginError: {
17621774
// 无可用插件
17631775
showErrorMessage(FI_Uncompress, EI_NoPlugin);
@@ -2101,6 +2113,10 @@ void MainWindow::showErrorMessage(FailureInfo fFailureInfo, ErrorInfo eErrorInfo
21012113
m_pFailurePage->setFailureDetail(tr("The compressed volumes already exist"));
21022114
}
21032115
break;
2116+
case EI_FileSeekError: {
2117+
m_pFailurePage->setFailureDetail(tr("No compression support in current directory. Download the files to a local device."));
2118+
}
2119+
break;
21042120
default:
21052121
break;
21062122
}
@@ -2127,6 +2143,10 @@ void MainWindow::showErrorMessage(FailureInfo fFailureInfo, ErrorInfo eErrorInfo
21272143
m_pFailurePage->setFailureDetail(tr("Some volumes are missing"));
21282144
}
21292145
break;
2146+
case EI_FileSeekError: {
2147+
m_pFailurePage->setFailureDetail(tr("Can't open compressed packages in current directory. Download the compressed package to a local device."));
2148+
}
2149+
break;
21302150
default:
21312151
break;
21322152
}
@@ -2168,6 +2188,10 @@ void MainWindow::showErrorMessage(FailureInfo fFailureInfo, ErrorInfo eErrorInfo
21682188
m_pFailurePage->setFailureDetail(tr("Insufficient disk space"));
21692189
}
21702190
break;
2191+
case EI_FileSeekError: {
2192+
m_pFailurePage->setFailureDetail(tr("No extraction support in current directory. Download the compressed package to a local device."));
2193+
}
2194+
break;
21712195
default:
21722196
break;
21732197
}

0 commit comments

Comments
 (0)