Skip to content

Commit 5cbbb8b

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 4ecb946 commit 5cbbb8b

File tree

1 file changed

+22
-26
lines changed

1 file changed

+22
-26
lines changed

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

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,14 @@ char *DEnumeratorPrivate::filePath(const QUrl &url)
377377

378378
QUrl DEnumeratorPrivate::buildUrl(const QUrl &url, const char *fileName)
379379
{
380-
auto path = url.path() == "/" ?
381-
"/" + QString(fileName) :
382-
url.path() + "/" + QString(fileName);
380+
QString path;
381+
if (url.path() == "/") {
382+
path = "/" + QString(fileName);
383+
} else {
384+
QString dirPath = url.path();
385+
path = dirPath.endsWith('/') ? dirPath + QString(fileName) : dirPath + "/" + QString(fileName);
386+
}
387+
383388
QUrl nextUrl = QUrl::fromLocalFile(path);
384389

385390
if (url.userInfo().startsWith("originPath::")) {
@@ -618,41 +623,32 @@ bool DEnumerator::hasNext() const
618623

619624
GFileEnumerator *enumerator = d->stackEnumerator.top();
620625

621-
GFileInfo *gfileInfo = nullptr;
622-
GFile *gfile = nullptr;
623-
624626
g_autoptr(GError) gerror = nullptr;
625627
d->checkAndResetCancel();
626-
bool hasNext = g_file_enumerator_iterate(enumerator, &gfileInfo, &gfile, d->cancellable, &gerror);
627-
if (hasNext) {
628-
if (!gfileInfo || !gfile) {
629-
GFileEnumerator *enumeratorPop = d->stackEnumerator.pop();
630-
g_object_unref(enumeratorPop);
631-
return this->hasNext();
632-
}
633628

634-
g_autofree gchar *path = g_file_get_path(gfile);
635-
if (path) {
636-
d->nextUrl = QUrl::fromLocalFile(QString::fromLocal8Bit(path));
637-
if (DFMUtils::isInvalidCodecByPath(path))
638-
d->nextUrl.setUserInfo(QString::fromLatin1("originPath::") + QString::fromLatin1(path));
639-
} else {
640-
g_autofree gchar *uri = g_file_get_uri(gfile);
641-
d->nextUrl = QUrl(QString::fromLocal8Bit(uri));
642-
if (DFMUtils::isInvalidCodecByPath(uri))
643-
d->nextUrl.setUserInfo(QString::fromLatin1("originPath::") + QString::fromLatin1(path));
644-
}
645-
d->dfileInfoNext = DLocalHelper::createFileInfoByUri(d->nextUrl, g_file_info_dup(gfileInfo), FILE_DEFAULT_ATTRIBUTES,
629+
// Use g_file_enumerator_next_file() which returns a GFileInfo* for the next
630+
// entry (or NULL). This avoids ambiguous iterate() behavior across backends.
631+
GFileInfo *nextInfo = g_file_enumerator_next_file(enumerator, d->cancellable, &gerror);
632+
if (nextInfo) {
633+
// Build URL from the name field (nextInfo may not include a GFile)
634+
d->nextUrl = d->buildUrl(d->uri, g_file_info_get_name(nextInfo));
635+
636+
d->dfileInfoNext = DLocalHelper::createFileInfoByUri(d->nextUrl, g_file_info_dup(nextInfo), FILE_DEFAULT_ATTRIBUTES,
646637
d->enumLinks ? DFileInfo::FileQueryInfoFlags::kTypeNone : DFileInfo::FileQueryInfoFlags::kTypeNoFollowSymlinks);
647638

639+
g_object_unref(nextInfo);
640+
648641
if (!d->checkFilter())
649642
return this->hasNext();
650643

651644
return true;
652645
}
653646

654-
if (gerror)
647+
// nextInfo == NULL: either finished or an error occurred
648+
if (gerror) {
655649
d->setErrorFromGError(gerror);
650+
return true;
651+
}
656652

657653
return false;
658654
}

0 commit comments

Comments
 (0)