https://bugs.kde.org/show_bug.cgi?id=509854
--- Comment #13 from firewalker <[email protected]> --- I tested the free version of Claude (An AI engine). After some back and forth with test programs it produced a patch that seems to solve the issue. Avoid nested event loop in dropEvent() for local files Konsole::TerminalDisplay::dropEvent() runs KIO::StatJob::exec() (via extractDroppedText() and setupCdToUrlAction()) before calling KIO::drop(event, ...). exec() spins a nested event loop. On Wayland this can destroy the data offer backing event->mimeData(), so KIO::drop() ends up constructing a QPointer from a dangling QMimeData* and crashes in QtSharedPointer::ExternalRefCountData::getAndRef(). Local files are already their own "most local URL", so skip the stat job for them and only use it for remote URLs. BUG: 509854 --- a/src/terminalDisplay/TerminalDisplay.cpp +++ b/src/terminalDisplay/TerminalDisplay.cpp @@ -3170,12 +3170,17 @@ { QString dropText; for (int i = 0; i < urls.count(); i++) { - KIO::StatJob *job = KIO::mostLocalUrl(urls[i], KIO::HideProgressInfo); - if (!job->exec()) { - continue; + QUrl url = urls[i]; + // Local files are already "most local". Only run the (blocking) stat job for + // other URLs: job->exec() spins a nested event loop, which must be avoided for + // local files inside dropEvent() (see the comment there). + if (!url.isLocalFile()) { + KIO::StatJob *job = KIO::mostLocalUrl(url, KIO::HideProgressInfo); + if (!job->exec()) { + continue; + } + url = job->mostLocalUrl(); } - - const QUrl url = job->mostLocalUrl(); // in future it may be useful to be able to insert file names with drag-and-drop // without quoting them (this only affects paths with spaces in) dropText += KShell::quoteArg(url.isLocalFile() ? url.path() : url.url()); @@ -3188,12 +3193,15 @@ void setupCdToUrlAction(const QString &dropText, const QUrl &url, QList<QAction *> &additionalActions, TerminalDisplay *display) { - KIO::StatJob *job = KIO::mostLocalUrl(url, KIO::HideProgressInfo); - if (!job->exec()) { - return; + QUrl localUrl = url; + if (!localUrl.isLocalFile()) { + // See extractDroppedText(): avoid the nested event loop for local files. + KIO::StatJob *job = KIO::mostLocalUrl(url, KIO::HideProgressInfo); + if (!job->exec()) { + return; + } + localUrl = job->mostLocalUrl(); } - - const QUrl localUrl = job->mostLocalUrl(); if (!localUrl.isLocalFile()) { return; } @@ -3229,7 +3237,10 @@ QString dropText; if (!urls.isEmpty()) { - // might invalidate mimeData thanks to job->exec() + // Beware: extractDroppedText() and setupCdToUrlAction() may run a nested event + // loop (job->exec()) for non-local URLs. On Wayland that can destroy the data + // offer behind mimeData, so KIO::drop() below would use a dangling pointer. + // They therefore skip the stat job for local files. dropText = extractDroppedText(urls); // If our target is local we will open a popup - otherwise the fallback kicks -- You are receiving this mail because: You are watching all bug changes.
