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.

Reply via email to