Propagator: Limit length of temporary file name #2789 (fixup)
authorMarkus Goetz <markus@woboq.com>
Mon, 11 May 2015 13:41:56 +0000 (15:41 +0200)
committerMarkus Goetz <markus@woboq.com>
Mon, 11 May 2015 13:42:35 +0000 (15:42 +0200)
Fix 22c35c4d15d31ab6fca3dfe4949ae807182bc481

csync/src/csync_exclude.c
src/libsync/propagatedownload.cpp
test/testowncloudpropagator.h

index f17e0974466b889eaae1c2fadac6a559ec7a7f04..484ad809ee4cb04304f670a7574170101df63cc0 100644 (file)
@@ -233,6 +233,7 @@ CSYNC_EXCLUDE_TYPE csync_excluded_no_ctx(c_strlist_t *excludes, const char *path
   }
 
   // check the strlen and ignore the file if its name is longer than 254 chars.
+  // whenever changing this also check createDownloadTmpFileName
   if (strlen(bname) > 254) {
       match = CSYNC_FILE_EXCLUDE_LONG_FILENAME;
       SAFE_FREE(bname);
index 98a966e002a4b04ba2b53e34fa038c2f86900c51..a0337488bc8177cbb2ee51b271f15d6931975461 100644 (file)
 namespace OCC {
 
 
+// Always coming in with forward slashes.
+// In csync_excluded_no_ctx we ignore all files with longer than 254 chars
+// This function also adds a dot at the begining of the filename to hide the file on OS X and Linux
 QString createDownloadTmpFileName(const QString &previous) {
-    QString tmpFileName = previous;
-    //add a dot at the begining of the filename to hide the file on OS X and Linux
-    int slashPos = tmpFileName.lastIndexOf('/');
-    tmpFileName.insert(slashPos+1, '.');
-    //add the suffix
-    tmpFileName += ".~" + QString::number(uint(qrand()), 16);
-
-    if (tmpFileName.length() > 254) { // https://github.com/owncloud/client/issues/2789
-        tmpFileName = tmpFileName.left(100) + "_" + tmpFileName.right(153);
+    QString tmpFileName;
+    QString tmpPath;
+    int slashPos = previous.lastIndexOf('/');
+    // work with both pathed filenames and only filenames
+    if (slashPos == -1) {
+        tmpFileName = previous;
+        tmpPath = QString();
+    } else {
+        tmpFileName = previous.mid(slashPos+1);
+        tmpPath = previous.left(slashPos);
+    }
+    int overhead =  1 + 1 + 2 + 8; // slash dot dot-tilde ffffffff"
+    int spaceForFileName = qMin(254, tmpFileName.length() + overhead) - overhead;
+    if (tmpPath.length() > 0) {
+        return tmpPath + '/' + '.' + tmpFileName.left(spaceForFileName) + ".~" + (QString::number(uint(qrand() % 0xFFFFFFFF), 16));
+    } else {
+        return '.' + tmpFileName.left(spaceForFileName) + ".~" + (QString::number(uint(qrand() % 0xFFFFFFFF), 16));
     }
-
-    return tmpFileName;
 }
 
 // DOES NOT take owncership of the device.
index 71e3a0d3f607f37a4e7045d4881860c622ed57f7..1ffa66a66b82c012bca2cc4251b4185156d4eb44 100644 (file)
@@ -31,9 +31,35 @@ private slots:
     void testTmpDownloadFileNameGeneration()
     {
         QString fn;
+        // without dir
+        for (int i = 1; i <= 1000; i++) {
+            fn+="F";
+            QString tmpFileName = createDownloadTmpFileName(fn);
+            if (tmpFileName.contains('/')) {
+                tmpFileName = tmpFileName.mid(tmpFileName.lastIndexOf('/')+1);
+            }
+            QVERIFY( tmpFileName.length() > 0);
+            QVERIFY( tmpFileName.length() <= 254);
+        }
+        // with absolute dir
+        fn = "/Users/guruz/ownCloud/rocks/GPL";
+        for (int i = 1; i < 1000; i++) {
+            fn+="F";
+            QString tmpFileName = createDownloadTmpFileName(fn);
+            if (tmpFileName.contains('/')) {
+                tmpFileName = tmpFileName.mid(tmpFileName.lastIndexOf('/')+1);
+            }
+            QVERIFY( tmpFileName.length() > 0);
+            QVERIFY( tmpFileName.length() <= 254);
+        }
+        // with relative dir
+        fn = "rocks/GPL";
         for (int i = 1; i < 1000; i++) {
             fn+="F";
             QString tmpFileName = createDownloadTmpFileName(fn);
+            if (tmpFileName.contains('/')) {
+                tmpFileName = tmpFileName.mid(tmpFileName.lastIndexOf('/')+1);
+            }
             QVERIFY( tmpFileName.length() > 0);
             QVERIFY( tmpFileName.length() <= 254);
         }