Bug 1443651: Don't return failure for access denied from createUnique() if file exists. r?Mossop draft
authorKris Maglione <maglione.k@gmail.com>
Tue, 06 Mar 2018 14:32:40 -0800
changeset 763952 b4d46241f809167bd6c146a15635f05d77e93bcb
parent 763951 76e86baa0273041bcae52aa6c398a185f597eb9b
push id101612
push usermaglione.k@gmail.com
push dateTue, 06 Mar 2018 22:34:20 +0000
reviewersMossop
bugs1443651
milestone60.0a1
Bug 1443651: Don't return failure for access denied from createUnique() if file exists. r?Mossop There are ways for Create() to return access denied for files which already exist, particularly in the case of locked files. When it does, createUnique() should check whether the file exists before considering the attempt a failure. MozReview-Commit-ID: FyJTghk04jH
browser/extensions/pocket/jar.mn
xpcom/io/nsLocalFileCommon.cpp
--- a/browser/extensions/pocket/jar.mn
+++ b/browser/extensions/pocket/jar.mn
@@ -1,10 +1,10 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 [features/firefox@getpocket.com] chrome.jar:
-% content pocket %content/ contentaccessible=yes
+% content pocket %content/
 % skin pocket-shared classic/1.0 %skin/shared/
   content/  (content/*)
   skin/shared (skin/shared/*)
 
--- a/xpcom/io/nsLocalFileCommon.cpp
+++ b/xpcom/io/nsLocalFileCommon.cpp
@@ -56,21 +56,29 @@ nsLocalFile::CreateUnique(uint32_t aType
 #else
   nsAutoCString pathName, leafName, rootName, suffix;
   rv = GetNativePath(pathName);
 #endif
   if (NS_FAILED(rv)) {
     return rv;
   }
 
+  auto FailedBecauseExists = [&] (nsresult aRv) {
+    if (aRv == NS_ERROR_FILE_ACCESS_DENIED) {
+      bool exists;
+      return NS_SUCCEEDED(Exists(&exists)) && exists;
+    }
+    return aRv == NS_ERROR_FILE_ALREADY_EXISTS;
+  };
+
   longName = (pathName.Length() + kMaxSequenceNumberLength >
               kMaxFilenameLength);
   if (!longName) {
     rv = Create(aType, aAttributes);
-    if (rv != NS_ERROR_FILE_ALREADY_EXISTS) {
+    if (!FailedBecauseExists(rv)) {
       return rv;
     }
   }
 
 #ifdef XP_WIN
   rv = GetLeafName(leafName);
   if (NS_FAILED(rv)) {
     return rv;
@@ -123,32 +131,32 @@ nsLocalFile::CreateUnique(uint32_t aType
         return NS_ERROR_FILE_UNRECOGNIZED_PATH;
       }
     }
 
     rootName.SetLength(maxRootLength);
     SetNativeLeafName(rootName + suffix);
 #endif
     nsresult rvCreate = Create(aType, aAttributes);
-    if (rvCreate != NS_ERROR_FILE_ALREADY_EXISTS) {
+    if (!FailedBecauseExists(rvCreate)) {
       return rvCreate;
     }
   }
 
   for (int indx = 1; indx < 10000; ++indx) {
     // start with "Picture-1.jpg" after "Picture.jpg" exists
 #ifdef XP_WIN
     SetLeafName(rootName +
                 NS_ConvertASCIItoUTF16(nsPrintfCString("-%d", indx)) +
                 suffix);
 #else
     SetNativeLeafName(rootName + nsPrintfCString("-%d", indx) + suffix);
 #endif
     rv = Create(aType, aAttributes);
-    if (NS_SUCCEEDED(rv) || rv != NS_ERROR_FILE_ALREADY_EXISTS) {
+    if (NS_SUCCEEDED(rv) || !FailedBecauseExists(rv)) {
       return rv;
     }
   }
 
   // The disk is full, sort of
   return NS_ERROR_FILE_TOO_BIG;
 }