Skip to content

Commit 039f26d

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 78aa60e commit 039f26d

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

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

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

382382
QUrl DEnumeratorPrivate::buildUrl(const QUrl &url, const char *fileName)
383383
{
384-
auto path = url.path() == "/" ?
385-
"/" + QString(fileName) :
386-
url.path() + "/" + QString(fileName);
384+
QString path;
385+
if (url.path() == "/") {
386+
path = "/" + QString(fileName);
387+
} else {
388+
QString dirPath = url.path();
389+
path = dirPath.endsWith('/') ? dirPath + QString(fileName) : dirPath + "/" + QString(fileName);
390+
}
391+
387392
QUrl nextUrl = QUrl::fromLocalFile(path);
388393

389394
if (url.userInfo().startsWith("originPath::")) {
@@ -622,41 +627,38 @@ bool DEnumerator::hasNext() const
622627

623628
GFileEnumerator *enumerator = d->stackEnumerator.top();
624629

625-
GFileInfo *gfileInfo = nullptr;
626-
GFile *gfile = nullptr;
627-
628630
g_autoptr(GError) gerror = nullptr;
629631
d->checkAndResetCancel();
630-
bool hasNext = g_file_enumerator_iterate(enumerator, &gfileInfo, &gfile, d->cancellable, &gerror);
631-
if (hasNext) {
632-
if (!gfileInfo || !gfile) {
633-
GFileEnumerator *enumeratorPop = d->stackEnumerator.pop();
634-
g_object_unref(enumeratorPop);
635-
return this->hasNext();
636-
}
637632

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

643+
g_object_unref(nextInfo);
644+
645+
if (gerror) {
646+
d->setErrorFromGError(gerror);
647+
g_error_free(gerror);
648+
gerror = nullptr;
649+
}
650+
652651
if (!d->checkFilter())
653652
return this->hasNext();
654653

655654
return true;
656655
}
657656

658-
if (gerror)
657+
// nextInfo == NULL: either finished or an error occurred
658+
if (gerror) {
659659
d->setErrorFromGError(gerror);
660+
return true;
661+
}
660662

661663
return false;
662664
}

0 commit comments

Comments
 (0)