Skip to content

Commit def2b7c

Browse files
committed
Fix: [file-enumerator] use g_file_enumerator_next_file()
--Replace use of g_file_enumerator_iterate() with g_file_enumerator_next_file() in DEnumerator::hasNext() so the enumerator's internal cursor is advanced by GIO and error/end conditions are handled unambiguously. --Using g_file_enumerator_next_file() yields clearer semantics: non-NULL -> next entry, NULL + NULL error -> end, NULL + non-NULL error -> error. This avoids premature termination caused by backend-specific iterate() quirks. --Construct next entry URL via the existing buildUrl(...) helper and preserve existing logic that creates the DFileInfo from the returned GFileInfo. Preserve existing error handling and d->checkFilter() behavior and recursive skipping of filtered entries. --Fix URL construction so joining directory path and filename does not introduce an extra '/' (previously produced e.g. .../vault_unlocked//file). The logic now concatenates carefully (handles root path and trailing slashes) to avoid duplicate separators. Log: fix issue Bug: https://pms.uniontech.com//bug-view-351177.html
1 parent 2769445 commit def2b7c

1 file changed

Lines changed: 19 additions & 27 deletions

File tree

src/dfm-io/dfm-io/denumerator.cpp

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,13 @@ char *DEnumeratorPrivate::filePath(const QUrl &url)
446446

447447
QUrl DEnumeratorPrivate::buildUrl(const QUrl &url, const char *fileName)
448448
{
449-
auto path = url.path() == "/" ?
450-
"/" + QString(fileName) :
451-
url.path() + "/" + QString(fileName);
449+
QString path;
450+
if (url.path() == "/") {
451+
path = "/" + QString(fileName);
452+
} else {
453+
QString dirPath = url.path();
454+
path = dirPath.endsWith('/') ? dirPath + QString(fileName) : dirPath + "/" + QString(fileName);
455+
}
452456
QUrl nextUrl = QUrl::fromLocalFile(path);
453457

454458
if (url.userInfo().startsWith("originPath::")) {
@@ -674,34 +678,19 @@ bool DEnumerator::hasNext() const
674678

675679
while (!d->stackEnumerator.isEmpty()) {
676680
GFileEnumerator *enumerator = d->stackEnumerator.top();
677-
GFileInfo *gfileInfo = nullptr;
678-
GFile *gfile = nullptr;
679681

680682
g_autoptr(GError) gerror = nullptr;
681683
d->checkAndResetCancel();
682-
bool hasNext = g_file_enumerator_iterate(enumerator, &gfileInfo, &gfile, d->cancellable, &gerror);
684+
// Use g_file_enumerator_next_file() which returns a GFileInfo* for the next
685+
// entry (or NULL). This avoids ambiguous iterate() behavior across backends.
686+
GFileInfo *nextInfo = g_file_enumerator_next_file(enumerator, d->cancellable, &gerror);
687+
if (nextInfo) {
688+
d->nextUrl = d->buildUrl(d->uri, g_file_info_get_name(nextInfo));
689+
d->dfileInfoNext = DLocalHelper::createFileInfoByUri(d->nextUrl, g_file_info_dup(nextInfo), FILE_DEFAULT_ATTRIBUTES,
690+
d->enumLinks ? DFileInfo::FileQueryInfoFlags::kTypeNone : DFileInfo::FileQueryInfoFlags::kTypeNoFollowSymlinks);
683691

684-
if (hasNext) {
685-
if (!gfileInfo || !gfile) {
686-
// 当前枚举器已完成,弹出并继续下一个
687-
GFileEnumerator *enumeratorPop = d->stackEnumerator.pop();
688-
g_object_unref(enumeratorPop);
689-
continue;
690-
}
691692

692-
g_autofree gchar *path = g_file_get_path(gfile);
693-
if (path) {
694-
d->nextUrl = QUrl::fromLocalFile(QString::fromLocal8Bit(path));
695-
if (DFMUtils::isInvalidCodecByPath(path))
696-
d->nextUrl.setUserInfo(QString::fromLatin1("originPath::") + QString::fromLatin1(path));
697-
} else {
698-
g_autofree gchar *uri = g_file_get_uri(gfile);
699-
d->nextUrl = QUrl(QString::fromLocal8Bit(uri));
700-
if (DFMUtils::isInvalidCodecByPath(uri))
701-
d->nextUrl.setUserInfo(QString::fromLatin1("originPath::") + QString::fromLatin1(path));
702-
}
703-
d->dfileInfoNext = DLocalHelper::createFileInfoByUri(d->nextUrl, g_file_info_dup(gfileInfo), FILE_DEFAULT_ATTRIBUTES,
704-
d->enumLinks ? DFileInfo::FileQueryInfoFlags::kTypeNone : DFileInfo::FileQueryInfoFlags::kTypeNoFollowSymlinks);
693+
g_object_unref(nextInfo);
705694

706695
// 如果是目录且需要遍历子目录
707696
if (d->enumSubDir && d->dfileInfoNext && d->dfileInfoNext->attribute(DFileInfo::AttributeID::kStandardIsDir).toBool()) {
@@ -720,9 +709,12 @@ bool DEnumerator::hasNext() const
720709
return true;
721710
}
722711

712+
// nextInfo == NULL: either finished or an error occurred
723713
if (gerror) {
724714
d->setErrorFromGError(gerror);
725-
return false;
715+
d->nextUrl = QUrl();
716+
d->dfileInfoNext.reset();
717+
return true;
726718
}
727719

728720
// 当前枚举器已完成,弹出并继续下一个

0 commit comments

Comments
 (0)