Bug 1598865 - do not use new hidden/system files detected in mail account local storage as mail folders. r=mkmelin
authoraceman <acelists@atlas.sk>
Tue, 03 Dec 2019 16:04:45 +0200
changeset 28303 375496910e9269c869326127e20186740d4a4259
parent 28302 e1257b911bd102b9983595dd3d0fd93ca999bbb9
child 28304 92f8935e6e88062280ef1667f3b93dc2f6b6873a
push id16756
push usermkmelin@iki.fi
push dateTue, 03 Dec 2019 14:06:19 +0000
treeherdercomm-central@375496910e92 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1598865
Bug 1598865 - do not use new hidden/system files detected in mail account local storage as mail folders. r=mkmelin
mailnews/imap/src/nsImapMailFolder.cpp
mailnews/local/src/nsMsgBrkMBoxStore.cpp
mailnews/local/src/nsMsgLocalStoreUtils.cpp
mailnews/local/src/nsMsgLocalStoreUtils.h
mailnews/local/src/nsMsgMaildirStore.cpp
--- a/mailnews/imap/src/nsImapMailFolder.cpp
+++ b/mailnews/imap/src/nsImapMailFolder.cpp
@@ -378,54 +378,52 @@ nsresult nsImapMailFolder::AddSubfolderW
 
   if (folder) mSubFolders.AppendObject(folder);
   folder.forget(child);
   return NS_OK;
 }
 
 nsresult nsImapMailFolder::CreateSubFolders(nsIFile *path) {
   nsresult rv = NS_OK;
-  nsAutoString currentFolderNameStr;    // online name
-  nsAutoString currentFolderDBNameStr;  // possibly munged name
-  nsCOMPtr<nsIMsgFolder> child;
   nsCOMPtr<nsIMsgIncomingServer> server;
   rv = GetServer(getter_AddRefs(server));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIDirectoryEnumerator> children;
-  rv = path->GetDirectoryEntries(getter_AddRefs(children));
-  bool more = false;
-  if (children) children->HasMoreElements(&more);
-
-  while (more) {
+  nsCOMPtr<nsIDirectoryEnumerator> directoryEnumerator;
+  rv = path->GetDirectoryEntries(getter_AddRefs(directoryEnumerator));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool hasMore = false;
+  while (NS_SUCCEEDED(directoryEnumerator->HasMoreElements(&hasMore)) &&
+         hasMore) {
     nsCOMPtr<nsIFile> currentFolderPath;
-    rv = children->GetNextFile(getter_AddRefs(currentFolderPath));
-    if (NS_FAILED(rv) || !currentFolderPath) break;
-    rv = children->HasMoreElements(&more);
-    if (NS_FAILED(rv)) return rv;
-
+    rv = directoryEnumerator->GetNextFile(getter_AddRefs(currentFolderPath));
+    if (NS_FAILED(rv) || !currentFolderPath) continue;
+
+    nsAutoString currentFolderNameStr;    // online name
+    nsAutoString currentFolderDBNameStr;  // possibly munged name
     currentFolderPath->GetLeafName(currentFolderNameStr);
     if (nsShouldIgnoreFile(currentFolderNameStr)) continue;
 
     // OK, here we need to get the online name from the folder cache if we can.
     // If we can, use that to create the sub-folder
-    nsCOMPtr<nsIMsgFolderCacheElement> cacheElement;
     nsCOMPtr<nsIFile> curFolder =
         do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     nsCOMPtr<nsIFile> dbFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     dbFile->InitWithFile(currentFolderPath);
     curFolder->InitWithFile(currentFolderPath);
     // don't strip off the .msf in currentFolderPath.
     currentFolderPath->SetLeafName(currentFolderNameStr);
     currentFolderDBNameStr = currentFolderNameStr;
     nsAutoString utf7LeafName = currentFolderNameStr;
 
     if (curFolder) {
+      nsCOMPtr<nsIMsgFolderCacheElement> cacheElement;
       rv = GetFolderCacheElemFromFile(dbFile, getter_AddRefs(cacheElement));
       if (NS_SUCCEEDED(rv) && cacheElement) {
         nsCString onlineFullUtf7Name;
 
         uint32_t folderFlags;
         rv = cacheElement->GetInt32Property("flags", (int32_t *)&folderFlags);
         if (NS_SUCCEEDED(rv) &&
             folderFlags & nsMsgFolderFlags::Virtual)  // ignore virtual folders
@@ -458,16 +456,17 @@ nsresult nsImapMailFolder::CreateSubFold
     NS_ENSURE_SUCCESS(rv, rv);
     msfFilePath->InitWithFile(currentFolderPath);
     if (NS_SUCCEEDED(rv) && msfFilePath) {
       // leaf name is the db name w/o .msf (nsShouldIgnoreFile strips it off)
       // so this trims the .msf off the file spec.
       msfFilePath->SetLeafName(currentFolderDBNameStr);
     }
     // use the utf7 name as the uri for the folder.
+    nsCOMPtr<nsIMsgFolder> child;
     AddSubfolderWithPath(utf7LeafName, msfFilePath, getter_AddRefs(child));
     if (child) {
       // use the unicode name as the "pretty" name. Set it so it won't be
       // automatically computed from the URI, which is in utf7 form.
       if (!currentFolderNameStr.IsEmpty())
         child->SetPrettyName(currentFolderNameStr);
       child->SetMsgDatabase(nullptr);
     }
--- a/mailnews/local/src/nsMsgBrkMBoxStore.cpp
+++ b/mailnews/local/src/nsMsgBrkMBoxStore.cpp
@@ -942,30 +942,32 @@ nsresult nsMsgBrkMBoxStore::AddSubFolder
   nsCOMPtr<nsIDirectoryEnumerator> directoryEnumerator;
   rv = path->GetDirectoryEntries(getter_AddRefs(directoryEnumerator));
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool hasMore;
   while (NS_SUCCEEDED(directoryEnumerator->HasMoreElements(&hasMore)) &&
          hasMore) {
     nsCOMPtr<nsIFile> currentFile;
-    directoryEnumerator->GetNextFile(getter_AddRefs(currentFile));
-    if (currentFile) currentDirEntries.AppendObject(currentFile);
+    rv = directoryEnumerator->GetNextFile(getter_AddRefs(currentFile));
+    if (NS_SUCCEEDED(rv) && currentFile) {
+      currentDirEntries.AppendObject(currentFile);
+    }
   }
 
   // add the folders
   int32_t count = currentDirEntries.Count();
   for (int32_t i = 0; i < count; ++i) {
     nsCOMPtr<nsIFile> currentFile(currentDirEntries[i]);
 
     nsAutoString leafName;
     currentFile->GetLeafName(leafName);
     // here we should handle the case where the current file is a .sbd directory
     // w/o a matching folder file, or a directory w/o the name .sbd
-    if (nsShouldIgnoreFile(leafName)) continue;
+    if (nsShouldIgnoreFile(leafName, currentFile)) continue;
 
     nsCOMPtr<nsIMsgFolder> child;
     rv = parent->AddSubfolder(leafName, getter_AddRefs(child));
     if (child) {
       nsString folderName;
       child->GetName(folderName);  // try to get it from cache/db
       if (folderName.IsEmpty()) child->SetPrettyName(leafName);
       if (deep) {
--- a/mailnews/local/src/nsMsgLocalStoreUtils.cpp
+++ b/mailnews/local/src/nsMsgLocalStoreUtils.cpp
@@ -16,17 +16,17 @@ nsMsgLocalStoreUtils::nsMsgLocalStoreUti
 
 nsresult nsMsgLocalStoreUtils::AddDirectorySeparator(nsIFile *path) {
   nsAutoString leafName;
   path->GetLeafName(leafName);
   leafName.AppendLiteral(FOLDER_SUFFIX);
   return path->SetLeafName(leafName);
 }
 
-bool nsMsgLocalStoreUtils::nsShouldIgnoreFile(nsAString &name) {
+bool nsMsgLocalStoreUtils::nsShouldIgnoreFile(nsAString &name, nsIFile *path) {
   if (name.IsEmpty()) return true;
 
   char16_t firstChar = name.First();
   if (firstChar == '.' || firstChar == '#' ||
       name.CharAt(name.Length() - 1) == '~')
     return true;
 
   if (name.LowerCaseEqualsLiteral("msgfilterrules.dat") ||
@@ -49,16 +49,24 @@ bool nsMsgLocalStoreUtils::nsShouldIgnor
   // ignore RSS data source files (see FeedUtils.jsm)
   if (name.LowerCaseEqualsLiteral("feeds.json") ||
       name.LowerCaseEqualsLiteral("feeditems.json") ||
       name.LowerCaseEqualsLiteral("feeds.rdf") ||
       name.LowerCaseEqualsLiteral("feeditems.rdf") ||
       StringBeginsWith(name, NS_LITERAL_STRING("feeditems_error")))
     return true;
 
+  // Ignore hidden and other special system files.
+  bool specialFile = false;
+  path->IsHidden(&specialFile);
+  if (specialFile) return true;
+  specialFile = false;
+  path->IsSpecial(&specialFile);
+  if (specialFile) return true;
+
   // The .mozmsgs dir is for spotlight support
   return (StringEndsWith(name, NS_LITERAL_STRING(".mozmsgs")) ||
           StringEndsWith(name, NS_LITERAL_STRING(FOLDER_SUFFIX)) ||
           StringEndsWith(name, NS_LITERAL_STRING(SUMMARY_SUFFIX)));
 }
 
 /**
  * We're passed a stream positioned at the start of the message.
--- a/mailnews/local/src/nsMsgLocalStoreUtils.h
+++ b/mailnews/local/src/nsMsgLocalStoreUtils.h
@@ -21,17 +21,17 @@
  * and MailDir stores inherit from this class to share some code.
  */
 
 class nsMsgLocalStoreUtils {
  public:
   nsMsgLocalStoreUtils();
 
   static nsresult AddDirectorySeparator(nsIFile *path);
-  static bool nsShouldIgnoreFile(nsAString &name);
+  static bool nsShouldIgnoreFile(nsAString &name, nsIFile *path);
   static void ChangeKeywordsHelper(nsIMsgDBHdr *message, uint64_t desiredOffset,
                                    nsLineBuffer<char> *lineBuffer,
                                    nsTArray<nsCString> &keywordArray, bool aAdd,
                                    nsIOutputStream *outputStream,
                                    nsISeekableStream *seekableStream,
                                    nsIInputStream *inputStream);
   static void ResetForceReparse(nsIMsgDatabase *aMsgDB);
 
--- a/mailnews/local/src/nsMsgMaildirStore.cpp
+++ b/mailnews/local/src/nsMsgMaildirStore.cpp
@@ -89,17 +89,17 @@ nsresult nsMsgMaildirStore::AddSubFolder
     rv = directoryEnumerator->GetNextFile(getter_AddRefs(currentFile));
     if (NS_SUCCEEDED(rv) && currentFile) {
       nsAutoString leafName;
       currentFile->GetLeafName(leafName);
       bool isDirectory = false;
       currentFile->IsDirectory(&isDirectory);
       // Make sure this really is a mail folder dir (i.e., a directory that
       // contains cur and tmp sub-dirs, and not a .sbd or .mozmsgs dir).
-      if (isDirectory && !nsShouldIgnoreFile(leafName))
+      if (isDirectory && !nsShouldIgnoreFile(leafName, currentFile))
         currentDirEntries.AppendObject(currentFile);
     }
   }
 
   // add the folders
   int32_t count = currentDirEntries.Count();
   for (int32_t i = 0; i < count; ++i) {
     nsCOMPtr<nsIFile> currentFile(currentDirEntries[i]);