https://bugs.kde.org/show_bug.cgi?id=411701
Harald Sitter <sit...@kde.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |sit...@kde.org Status|REOPENED |CONFIRMED --- Comment #8 from Harald Sitter <sit...@kde.org> --- This is a fairly non-trivial problem. ftpSendCmd will try to establish a connection when it stopped working for some reason. if that re-establishing still goes wrong the connection is closed as a whole (ftpCloseControlConnection) which means m_control is set to nullptr. This clashes with fallback logic in various parts of the code. Notably I've seen: listDir() will call ftpFileExists() after ftpOpenDir() already failed. m_control is nullptr at this point already and fails the assert in ftpSendCmd(). inside ftpOpenDir() if by chance the call made it past ftpFolder() it will call ftpOpenCommand() which calls ftpOpenDataConnection() and that has a similar defect: it calls ftpOpenPASVDataConnection() which can error out on connection establishment but then tries to recover by calling ftpOpenEPSVDataConnection() which again fails because m_control is already null again. I am profoundly unsure how to best fix this. Perhaps the assertions should really be return conditions. test scenario for the record though: ``` void testCrashOnServerDisappearance() { QProcess daemonProc; QUrl url = QUrl("ftp://localhost"); runDaemon(daemonProc, url, m_remoteDir); url.setPath("/"); // Server disappears after first list and slave crashes // subsequently. // https://bugs.kde.org/show_bug.cgi?id=411701 { auto job = KIO::listDir(url); job->setUiDelegate(nullptr); QVERIFY2(job->exec(), qUtf8Printable(job->errorString())); QCOMPARE(job->error(), 0); } daemonProc.kill(); QVERIFY(daemonProc.waitForFinished()); { auto job = KIO::listDir(url); job->setUiDelegate(nullptr); QVERIFY2(job->exec(), qUtf8Printable(job->errorString())); QCOMPARE(job->error(), 0); } } ``` -- You are receiving this mail because: You are watching all bug changes.