diff --git a/autotests/jobtest.h b/autotests/jobtest.h --- a/autotests/jobtest.h +++ b/autotests/jobtest.h @@ -97,6 +97,8 @@ void moveDestAlreadyExistsAutoRename_data(); void moveDestAlreadyExistsAutoRename(); + void copyDirectoryAlreadyExistsSkip(); + void safeOverwrite(); void safeOverwrite_data(); void moveAndOverwrite(); diff --git a/autotests/jobtest.cpp b/autotests/jobtest.cpp --- a/autotests/jobtest.cpp +++ b/autotests/jobtest.cpp @@ -1732,6 +1732,37 @@ } } +void JobTest::copyDirectoryAlreadyExistsSkip() +{ + // when copying a directory (which contains at least one file) to some location, and then + // copying the same dir to the same location again, and clicking "Skip" there should be no + // segmentation fault, bug 408350 + + const QString src = homeTmpDir() + "a"; + createTestDirectory(src); + const QString dest = homeTmpDir() + "dest"; + createTestDirectory(dest); + + QUrl u = QUrl::fromLocalFile(src); + QUrl d = QUrl::fromLocalFile(dest); + + KIO::Job *job = KIO::copy(u, d, KIO::HideProgressInfo); + job->setUiDelegate(nullptr); + QVERIFY(job->exec()); + QVERIFY(QFile::exists(dest + QStringLiteral("/a/testfile"))); + + job = KIO::copy(u, d, KIO::HideProgressInfo); + // Simulate the user pressing "Skip" in the dialog. + PredefinedAnswerJobUiDelegate extension; + extension.m_skipResult = KIO::S_SKIP; + job->setUiDelegateExtension(&extension); + QVERIFY(job->exec()); + QVERIFY(QFile::exists(dest + QStringLiteral("/a/testfile"))); + + QDir(src).removeRecursively(); + QDir(dest).removeRecursively(); +} + void JobTest::safeOverwrite_data() { QTest::addColumn("destFileExists"); diff --git a/src/core/copyjob.cpp b/src/core/copyjob.cpp --- a/src/core/copyjob.cpp +++ b/src/core/copyjob.cpp @@ -1637,7 +1637,7 @@ it = files.erase(it); } - if ((*it).size > ((1ul << 32) - 1)) { // ((1ul << 32) - 1) = 4 GB + if (it != files.end() && (*it).size > ((1ul << 32) - 1)) { // ((1ul << 32) - 1) = 4 GB const auto fileSystem = KFileSystemType::fileSystemType(m_globalDest.toLocalFile()); if (fileSystem == KFileSystemType::Fat) { q->setError(ERR_FILE_TOO_LARGE_FOR_FAT32);