[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/kio
From:       David Faure <faure () kde ! org>
Date:       2008-08-11 8:07:18
Message-ID: 1218442038.178024.6662.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 845067 by dfaure:

Fix crash when skipping a source URL in the direct-renaming phase
BUG: 157601


 M  +20 -6     kio/copyjob.cpp  
 M  +9 -0      kio/copyjob.h  
 M  +19 -0     tests/jobtest.cpp  
 M  +1 -0      tests/jobtest.h  


--- trunk/KDE/kdelibs/kio/kio/copyjob.cpp #845066:845067
@@ -151,6 +151,7 @@
     QList<CopyInfo> dirs;
     KUrl::List dirsToRemove;
     KUrl::List m_srcList;
+    KUrl::List m_skippedSourceUrls;
     KUrl::List::const_iterator m_currentStatSrc;
     bool m_bCurrentSrcIsDir;
     bool m_bCurrentOperationIsLink;
@@ -768,8 +769,8 @@
 {
     // If this is one if toplevel sources,
     // remove it from d->m_srcList, for a correct FilesRemoved() signal
-    //kDebug(7007) << "looking for " << sourceUrl;
-    m_srcList.removeAll( sourceUrl );
+    // But don't do it right away, we have iterators into that list (#157601)
+    m_skippedSourceUrls.append( sourceUrl );
     dirsToRemove.removeAll( sourceUrl );
 }
 
@@ -1513,6 +1514,9 @@
             //kDebug(7007) << "KDirNotify'ing FilesAdded " << url;
             org::kde::KDirNotify::emitFilesAdded( url.url() );
 
+            Q_FOREACH(const KUrl& url, m_skippedSourceUrls)
+                m_srcList.removeAll(url);
+
             if ( m_mode == CopyJob::Move && !m_srcList.isEmpty() ) {
                 //kDebug(7007) << "KDirNotify'ing FilesRemoved " << \
                m_srcList.toStringList();
                 org::kde::KDirNotify::emitFilesRemoved( m_srcList.toStringList() );
@@ -1657,10 +1661,9 @@
         Q_ASSERT( m_currentSrcURL == *m_currentStatSrc );
 
         // Existing dest?
-        if ( ( err == ERR_DIR_ALREADY_EXIST ||
+        if ( err == ERR_DIR_ALREADY_EXIST ||
                err == ERR_FILE_ALREADY_EXIST ||
                err == ERR_IDENTICAL_FILES )
-             && q->isInteractive() )
         {
             if (m_reportTimer)
                 m_reportTimer->stop();
@@ -1672,7 +1675,7 @@
                 return;
             } else if ( m_bOverwriteAll ) {
                 ; // nothing to do, stat+copy+del will overwrite
-            } else {
+            } else if ( q->isInteractive() ) {
                 QString newPath;
                 // If src==dest, use "overwrite-itself"
                 RenameDialog_Mode mode = (RenameDialog_Mode)
@@ -1761,6 +1764,12 @@
                     //assert( 0 );
                     break;
                 }
+            } else if ( err != KIO::ERR_UNSUPPORTED_ACTION ) {
+                // Dest already exists, and job is not interactive -> abort with \
error +                q->setError( err );
+                q->setErrorText( errText );
+                q->emitResult();
+                return;
             }
         } else if ( err != KIO::ERR_UNSUPPORTED_ACTION ) {
             kDebug(7007) << "Couldn't rename" << m_currentSrcURL << "to" << dest << \
", aborting"; @@ -1778,7 +1787,7 @@
     }
     else
     {
-        //kDebug(7007) << "Renaming succeeded, move on";
+        kDebug(7007) << "Renaming succeeded, move on";
         ++m_processedFiles;
         emit q->copyingDone( q, *m_currentStatSrc, dest, -1 /*mtime unknown, and not \
needed*/, true, true );  statNextSrc();
@@ -1850,6 +1859,11 @@
     return d_func()->m_mode;
 }
 
+void KIO::CopyJob::setAutoSkip(bool autoSkip)
+{
+    d_func()->m_bAutoSkip = autoSkip;
+}
+
 CopyJob *KIO::copy(const KUrl& src, const KUrl& dest, JobFlags flags)
 {
     //kDebug(7007) << "src=" << src << "dest=" << dest;
--- trunk/KDE/kdelibs/kio/kio/copyjob.h #845066:845067
@@ -102,6 +102,15 @@
         void setDefaultPermissions( bool b );
 
         /**
+         * Skip copying or moving any file when the destination already exists,
+         * instead of the default behavior (interactive mode: showing a dialog to \
the user, +         * non-interactive mode: aborting with an error).
+         * Initially added for a unit test.
+         * \since 4.2
+         */
+        void setAutoSkip(bool autoSkip);
+
+        /**
          * Reimplemented for internal reasons
          */
         virtual bool doSuspend();
--- trunk/KDE/kdelibs/kio/tests/jobtest.cpp #845066:845067
@@ -1167,4 +1167,23 @@
 #endif
 }
 
+void JobTest::moveFileDestAlreadyExists() // #157601
+{
+    const QString file1 = homeTmpDir() + "fileFromHome";
+    createTestFile( file1 );
+    const QString file2 = homeTmpDir() + "anotherFile";
+    createTestFile( file2 );
+    const QString existingDest = otherTmpDir() + "fileFromHome";
+    createTestFile( existingDest );
+
+    KUrl::List urls; urls << KUrl(file1) << KUrl(file2);
+    KIO::CopyJob* job = KIO::move(urls, otherTmpDir(), KIO::HideProgressInfo);
+    job->setUiDelegate(0);
+    job->setAutoSkip(true);
+    bool ok = KIO::NetAccess::synchronousRun(job, 0);
+    QVERIFY(ok);
+    QVERIFY(QFile::exists(file1)); // it was skipped
+    QVERIFY(!QFile::exists(file2)); // it was moved
+}
+
 #include "jobtest.moc"
--- trunk/KDE/kdelibs/kio/tests/jobtest.h #845066:845067
@@ -60,6 +60,7 @@
     void mimeType();
     //void newApiPerformance();
     void calculateRemainingSeconds();
+    void moveFileDestAlreadyExists();
 
     // Remote tests
     //void copyFileToSystem();


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic