[tor-commits] [tor-messenger-build/updater] Add patch for #14631

sukhbir at torproject.org sukhbir at torproject.org
Fri Jul 29 17:20:47 UTC 2016


commit d4f35015683bedf07194f3982e080641eb0ff27f
Author: Sukhbir Singh <sukhbir at torproject.org>
Date:   Mon Jul 18 12:40:15 2016 -0400

    Add patch for #14631
---
 ...Improve-profile-access-bug-14631-first.mozpatch | 246 +++++++++++++++++++++
 ...mprove-profile-access-bug-14631-second.mozpatch | 182 +++++++++++++++
 2 files changed, 428 insertions(+)

diff --git a/projects/instantbird/Improve-profile-access-bug-14631-first.mozpatch b/projects/instantbird/Improve-profile-access-bug-14631-first.mozpatch
new file mode 100644
index 0000000..7a9ad68
--- /dev/null
+++ b/projects/instantbird/Improve-profile-access-bug-14631-first.mozpatch
@@ -0,0 +1,246 @@
+commit 5aae044b37579dc1c95b195084bcfcdaed352545
+Author: Kathy Brade <brade at pearlcrescent.com>
+Date:   Tue Feb 24 13:50:23 2015 -0500
+
+    Bug 14631: Improve profile access error messages.
+    
+    Instead of always reporting that the profile is locked, display specific
+    messages for "access denied" and "read-only file system".
+
+diff --git a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
+index adac95a..3cf48ff 100644
+--- a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
++++ b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
+@@ -12,6 +12,11 @@ restartMessageUnlocker=%S is already running, but is not responding. The old %S
+ restartMessageNoUnlockerMac=A copy of %S is already open. Only one copy of %S can be open at a time.
+ restartMessageUnlockerMac=A copy of %S is already open. The running copy of %S will quit in order to open this one.
+ 
++# LOCALIZATION NOTE (profileProblemTitle, profileReadOnly, profileReadOnlyMac, profileAccessDenied):  Messages displayed when the browser profile cannot be accessed or written to. %S is the application name.
++profileProblemTitle=%S Profile Problem
++profileReadOnly=You cannot run %S from a read-only file system.  Please copy %S to another location before trying to use it.
++profileReadOnlyMac=You cannot run %S from a read-only file system.  Please copy %S to your Desktop or Applications folder before trying to use it.
++profileAccessDenied=%S does not have permission to access the profile. Please adjust your file system permissions and try again.
+ # Profile manager
+ # LOCALIZATION NOTE (profileTooltip): First %S is the profile name, second %S is the path to the profile folder.
+ profileTooltip=Profile: '%S' - Path: '%S'
+diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
+index da73cd5..d82f303 100644
+--- a/toolkit/xre/nsAppRunner.cpp
++++ b/toolkit/xre/nsAppRunner.cpp
+@@ -1913,6 +1913,14 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative,
+   return NS_ERROR_LAUNCHED_CHILD_PROCESS;
+ }
+ 
++enum ProfileStatus {
++  PROFILE_STATUS_OK,
++  PROFILE_STATUS_ACCESS_DENIED,
++  PROFILE_STATUS_READ_ONLY,
++  PROFILE_STATUS_IS_LOCKED,
++  PROFILE_STATUS_OTHER_ERROR
++};
++
+ static const char kProfileProperties[] =
+   "chrome://mozapps/locale/profile/profileSelection.properties";
+ 
+@@ -1951,9 +1959,9 @@ private:
+ } // namespace
+ 
+ static ReturnAbortOnError
+-ProfileLockedDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+-                    nsIProfileUnlocker* aUnlocker,
+-                    nsINativeAppSupport* aNative, nsIProfileLock* *aResult)
++ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
++                   ProfileStatus aStatus, nsIProfileUnlocker* aUnlocker,
++                   nsINativeAppSupport* aNative, nsIProfileLock* *aResult)
+ {
+   nsresult rv;
+ 
+@@ -1980,18 +1988,31 @@ ProfileLockedDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+ 
+     nsXPIDLString killMessage;
+ #ifndef XP_MACOSX
+-    sb->FormatStringFromName(aUnlocker ? MOZ_UTF16("restartMessageUnlocker")
+-                                       : MOZ_UTF16("restartMessageNoUnlocker"),
+-                             params, 2, getter_Copies(killMessage));
++    static const char16_t kRestartUnlocker[] = MOZ_UTF16("restartMessageUnlocker");
++    static const char16_t kRestartNoUnlocker[] = MOZ_UTF16("restartMessageNoUnlocker");
++    static const char16_t kReadOnly[] = MOZ_UTF16("profileReadOnly");
+ #else
+-    sb->FormatStringFromName(aUnlocker ? MOZ_UTF16("restartMessageUnlockerMac")
+-                                       : MOZ_UTF16("restartMessageNoUnlockerMac"),
+-                             params, 2, getter_Copies(killMessage));
++    static const char16_t kRestartUnlocker[] = MOZ_UTF16("restartMessageUnlockerMac");
++    static const char16_t kRestartNoUnlocker[] = MOZ_UTF16("restartMessageNoUnlockerMac");
++    static const char16_t kReadOnly[] = MOZ_UTF16("profileReadOnlyMac");
+ #endif
++    static const char16_t kAccessDenied[] = MOZ_UTF16("profileAccessDenied");
++ 
++    const char16_t *errorKey = aUnlocker ? kRestartUnlocker
++                                         : kRestartNoUnlocker;
++    if (PROFILE_STATUS_READ_ONLY == aStatus)
++      errorKey = kReadOnly;
++    else if (PROFILE_STATUS_ACCESS_DENIED == aStatus)
++      errorKey = kAccessDenied;
++    sb->FormatStringFromName(errorKey, params, 2, getter_Copies(killMessage));
++
++    const char16_t *titleKey = ((PROFILE_STATUS_READ_ONLY == aStatus) ||
++                                (PROFILE_STATUS_ACCESS_DENIED == aStatus))
++                                   ? MOZ_UTF16("profileProblemTitle")
++                                   : MOZ_UTF16("restartTitle");
+ 
+     nsXPIDLString killTitle;
+-    sb->FormatStringFromName(MOZ_UTF16("restartTitle"),
+-                             params, 1, getter_Copies(killTitle));
++    sb->FormatStringFromName(titleKey, params, 1, getter_Copies(killTitle));
+ 
+     if (!killMessage || !killTitle)
+       return NS_ERROR_FAILURE;
+@@ -2092,8 +2113,9 @@ ProfileMissingDialog(nsINativeAppSupport* aNative)
+ }
+ 
+ static nsresult
+-ProfileLockedDialog(nsIToolkitProfile* aProfile, nsIProfileUnlocker* aUnlocker,
+-                    nsINativeAppSupport* aNative, nsIProfileLock* *aResult)
++ProfileErrorDialog(nsIToolkitProfile* aProfile, ProfileStatus aStatus,
++                   nsIProfileUnlocker* aUnlocker, nsINativeAppSupport* aNative,
++                   nsIProfileLock* *aResult)
+ {
+   nsCOMPtr<nsIFile> profileDir;
+   nsresult rv = aProfile->GetRootDir(getter_AddRefs(profileDir));
+@@ -2109,8 +2131,8 @@ ProfileLockedDialog(nsIToolkitProfile* aProfile, nsIProfileUnlocker* aUnlocker,
+   rv = aProfile->GetLocalDir(getter_AddRefs(profileLocalDir));
+   if (NS_FAILED(rv)) return rv;
+ 
+-  return ProfileLockedDialog(profileDir, profileLocalDir, aUnlocker, aNative,
+-                             aResult);
++  return ProfileErrorDialog(profileDir, profileLocalDir, aStatus, aUnlocker,
++                            aNative, aResult);
+ }
+ 
+ static const char kProfileManagerURL[] =
+@@ -2275,6 +2297,53 @@ SetCurrentProfileAsDefault(nsIToolkitProfileService* aProfileSvc,
+   return rv;
+ }
+ 
++// Check for write permission to the profile directory by trying to create a
++// new file (after ensuring that no file with the same name exists).
++static ProfileStatus CheckProfileWriteAccess(nsIFile* aProfileDir)
++{
++#if defined(XP_UNIX)
++  NS_NAMED_LITERAL_STRING(writeTestFileName, ".parentwritetest");
++#else
++  NS_NAMED_LITERAL_STRING(writeTestFileName, "parent.writetest");
++#endif
++
++  nsCOMPtr<nsIFile> writeTestFile;
++  nsresult rv = aProfileDir->Clone(getter_AddRefs(writeTestFile));
++  if (NS_SUCCEEDED(rv))
++    rv = writeTestFile->Append(writeTestFileName);
++
++  if (NS_SUCCEEDED(rv)) {
++    bool doesExist = false;
++    rv = writeTestFile->Exists(&doesExist);
++    if (NS_SUCCEEDED(rv) && doesExist)
++      rv = writeTestFile->Remove(true);
++  }
++
++  if (NS_SUCCEEDED(rv)) {
++    rv = writeTestFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
++    (void)writeTestFile->Remove(true);
++  }
++
++  ProfileStatus status = NS_SUCCEEDED(rv) ? PROFILE_STATUS_OK
++                                          : PROFILE_STATUS_OTHER_ERROR;
++  if (NS_ERROR_FILE_ACCESS_DENIED == rv)
++    status = PROFILE_STATUS_ACCESS_DENIED;
++  else if (NS_ERROR_FILE_READ_ONLY == rv)
++    status = PROFILE_STATUS_READ_ONLY;
++
++  return status;
++}
++
++static ProfileStatus CheckProfileWriteAccess(nsIToolkitProfile* aProfile)
++{
++  nsCOMPtr<nsIFile> profileDir;
++  nsresult rv = aProfile->GetRootDir(getter_AddRefs(profileDir));
++  if (NS_FAILED(rv))
++    return PROFILE_STATUS_OTHER_ERROR;
++
++  return CheckProfileWriteAccess(profileDir);
++}
++
+ static bool gDoMigration = false;
+ static bool gDoProfileReset = false;
+ 
+@@ -2410,13 +2479,18 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+         NS_ENSURE_SUCCESS(rv, rv);
+     }
+ 
++    ProfileStatus status = CheckProfileWriteAccess(lf);
++    if (PROFILE_STATUS_OK != status)
++      return ProfileErrorDialog(lf, lf, status, nullptr, aNative, aResult);
++
+     // If a profile path is specified directory on the command line, then
+     // assume that the temp directory is the same as the given directory.
+     rv = NS_LockProfilePath(lf, lf, getter_AddRefs(unlocker), aResult);
+     if (NS_SUCCEEDED(rv))
+       return rv;
+ 
+-    return ProfileLockedDialog(lf, lf, unlocker, aNative, aResult);
++    return ProfileErrorDialog(lf, lf, PROFILE_STATUS_IS_LOCKED, unlocker,
++                              aNative, aResult);
+   }
+ 
+   ar = CheckArg("createprofile", true, &arg);
+@@ -2501,6 +2575,10 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+         gDoProfileReset = false;
+       }
+ 
++      ProfileStatus status = CheckProfileWriteAccess(profile);
++      if (PROFILE_STATUS_OK != status)
++        return ProfileErrorDialog(profile, status, nullptr, aNative, aResult);
++
+       nsCOMPtr<nsIProfileUnlocker> unlocker;
+       rv = profile->Lock(getter_AddRefs(unlocker), aResult);
+       if (NS_SUCCEEDED(rv)) {
+@@ -2509,7 +2587,8 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+         return NS_OK;
+       }
+ 
+-      return ProfileLockedDialog(profile, unlocker, aNative, aResult);
++      return ProfileErrorDialog(profile, PROFILE_STATUS_IS_LOCKED, unlocker,
++                                aNative, aResult);
+     }
+ 
+     if (CanShowProfileManager()) {
+@@ -2589,7 +2668,8 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+           nsCOMPtr<nsIProfileUnlocker> unlocker;
+           rv = profile->Lock(getter_AddRefs(unlocker), &tempProfileLock);
+           if (NS_FAILED(rv))
+-            return ProfileLockedDialog(profile, unlocker, aNative, &tempProfileLock);
++            return ProfileErrorDialog(profile, PROFILE_STATUS_IS_LOCKED,
++                                      unlocker, aNative, &tempProfileLock);
+         }
+ 
+         nsCOMPtr<nsIToolkitProfile> newProfile;
+@@ -2600,6 +2680,10 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+           gDoProfileReset = false;
+       }
+ 
++      ProfileStatus status = CheckProfileWriteAccess(profile);
++      if (PROFILE_STATUS_OK != status)
++        return ProfileErrorDialog(profile, status, nullptr, aNative, aResult);
++
+       // If you close Firefox and very quickly reopen it, the old Firefox may
+       // still be closing down. Rather than immediately showing the
+       // "Firefox is running but is not responding" message, we spend a few
+@@ -2625,7 +2709,8 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+         PR_Sleep(kLockRetrySleepMS);
+       } while (TimeStamp::Now() - start < TimeDuration::FromSeconds(kLockRetrySeconds));
+ 
+-      return ProfileLockedDialog(profile, unlocker, aNative, aResult);
++      return ProfileErrorDialog(profile, PROFILE_STATUS_IS_LOCKED, unlocker,
++                                aNative, aResult);
+     }
+   }
+ 
diff --git a/projects/instantbird/Improve-profile-access-bug-14631-second.mozpatch b/projects/instantbird/Improve-profile-access-bug-14631-second.mozpatch
new file mode 100644
index 0000000..3e59cd5
--- /dev/null
+++ b/projects/instantbird/Improve-profile-access-bug-14631-second.mozpatch
@@ -0,0 +1,182 @@
+commit 303992b0684036f6f23d1ca7f76b360930f510db
+Author: Kathy Brade <brade at pearlcrescent.com>
+Date:   Fri Feb 27 10:38:40 2015 -0500
+
+    Bug 14631: Improve profile access error msgs (strings).
+    
+    To allow for localization, get profile-related error strings from Torbutton.
+    Use app display name ("Tor Browser") in profile-related error alerts.
+
+diff --git a/toolkit/xre/moz.build b/toolkit/xre/moz.build
+index d8127a6..3e6a3b6 100644
+--- a/toolkit/xre/moz.build
++++ b/toolkit/xre/moz.build
+@@ -116,8 +116,8 @@ FINAL_LIBRARY = 'xul'
+ if CONFIG['MOZ_GL_DEFAULT_PROVIDER'] == 'GLX':
+     DEFINES['USE_GLX_TEST'] = True
+ 
+-for var in ('MOZ_APP_NAME', 'MOZ_APP_BASENAME', 'MOZ_APP_VERSION', 'OS_TARGET',
+-            'MOZ_WIDGET_TOOLKIT'):
++for var in ('MOZ_APP_NAME', 'MOZ_APP_BASENAME', 'MOZ_APP_DISPLAYNAME',
++            'MOZ_APP_VERSION', 'OS_TARGET', 'MOZ_WIDGET_TOOLKIT'):
+     DEFINES[var] = '"%s"' % CONFIG[var]
+ 
+ if CONFIG['MOZ_UPDATER'] and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
+diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
+index d82f303..a7c7d75 100644
+--- a/toolkit/xre/nsAppRunner.cpp
++++ b/toolkit/xre/nsAppRunner.cpp
+@@ -1913,6 +1913,104 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative,
+   return NS_ERROR_LAUNCHED_CHILD_PROCESS;
+ }
+ 
++static nsresult
++GetOverrideStringBundleForLocale(nsIStringBundleService* aSBS,
++                                 const char* aTorbuttonURI, const char* aLocale,
++                                 nsIStringBundle* *aResult)
++{
++  NS_ENSURE_ARG(aSBS);
++  NS_ENSURE_ARG(aTorbuttonURI);
++  NS_ENSURE_ARG(aLocale);
++  NS_ENSURE_ARG(aResult);
++
++  const char* kFormatStr = "jar:%s!/chrome/locale/%s/torbutton.properties";
++  nsPrintfCString strBundleURL(kFormatStr, aTorbuttonURI, aLocale);
++  nsresult rv = aSBS->CreateBundle(strBundleURL.get(), aResult);
++  NS_ENSURE_SUCCESS(rv, rv);
++
++  // To ensure that we have a valid string bundle, try to retrieve a string
++  // that we know exists.
++  nsXPIDLString val;
++  rv = (*aResult)->GetStringFromName(MOZ_UTF16("profileProblemTitle"),
++                                     getter_Copies(val));
++  if (!NS_SUCCEEDED(rv))
++    *aResult = nullptr;  // No good.  Discard it.
++
++  return rv;
++}
++
++static void
++GetOverrideStringBundle(nsIStringBundleService* aSBS, nsIStringBundle* *aResult)
++{
++  if (!aSBS || !aResult)
++    return;
++
++  *aResult = nullptr;
++
++  // Build Torbutton file URI string by starting from the profiles directory.
++  nsXREDirProvider* dirProvider = nsXREDirProvider::GetSingleton();
++  if (!dirProvider)
++    return;
++
++  bool persistent = false; // ignored
++  nsCOMPtr<nsIFile> profilesDir;
++  nsresult rv = dirProvider->GetFile(NS_APP_USER_PROFILES_ROOT_DIR, &persistent,
++                                     getter_AddRefs(profilesDir));
++  if (NS_FAILED(rv))
++    return;
++
++  // Create file URI, extract as string, and append Torbutton xpi relative path.
++  nsCOMPtr<nsIURI> uri;
++  nsAutoCString uriString;
++  if (NS_FAILED(NS_NewFileURI(getter_AddRefs(uri), profilesDir)) ||
++      NS_FAILED(uri->GetSpec(uriString))) {
++    return;
++  }
++
++  uriString.Append("profile.default/extensions/torbutton at torproject.org.xpi");
++
++  nsCString userAgentLocale;
++  if (!NS_SUCCEEDED(Preferences::GetCString("general.useragent.locale",
++                                            &userAgentLocale))) {
++    return;
++  }
++
++  rv = GetOverrideStringBundleForLocale(aSBS, uriString.get(),
++                                   userAgentLocale.get(), aResult);
++  if (NS_FAILED(rv)) {
++    // Try again using base locale, e.g., "en" vs. "en-US".
++    int16_t offset = userAgentLocale.FindChar('-', 1);
++    if (offset > 0) {
++      nsAutoCString shortLocale(Substring(userAgentLocale, 0, offset));
++      rv = GetOverrideStringBundleForLocale(aSBS, uriString.get(),
++                                       shortLocale.get(), aResult);
++    }
++  }
++}
++
++static nsresult
++GetFormattedString(nsIStringBundle* aOverrideBundle,
++                   nsIStringBundle* aMainBundle,
++                   const char16_t* aName,
++                   const char16_t** aParams, uint32_t aLength,
++                   char16_t* *aResult)
++{
++  NS_ENSURE_ARG(aName);
++  NS_ENSURE_ARG(aResult);
++
++  nsresult rv = NS_ERROR_FAILURE;
++  if (aOverrideBundle) {
++    rv = aOverrideBundle->FormatStringFromName(aName, aParams, aLength,
++                                               aResult);
++  }
++
++  // If string was not found in override bundle, use main (browser) bundle.
++  if (NS_FAILED(rv) && aMainBundle)
++    rv = aMainBundle->FormatStringFromName(aName, aParams, aLength, aResult);
++
++  return rv;
++}
++
+ enum ProfileStatus {
+   PROFILE_STATUS_OK,
+   PROFILE_STATUS_ACCESS_DENIED,
+@@ -1983,7 +2081,10 @@ ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+     sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
+     NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE);
+ 
+-    NS_ConvertUTF8toUTF16 appName(gAppData->name);
++    nsCOMPtr<nsIStringBundle> overrideSB;
++    GetOverrideStringBundle(sbs, getter_AddRefs(overrideSB));
++
++    NS_ConvertUTF8toUTF16 appName(MOZ_APP_DISPLAYNAME);
+     const char16_t* params[] = {appName.get(), appName.get()};
+ 
+     nsXPIDLString killMessage;
+@@ -1998,21 +2099,23 @@ ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+ #endif
+     static const char16_t kAccessDenied[] = MOZ_UTF16("profileAccessDenied");
+  
+-    const char16_t *errorKey = aUnlocker ? kRestartUnlocker
++    const char16_t* errorKey = aUnlocker ? kRestartUnlocker
+                                          : kRestartNoUnlocker;
+     if (PROFILE_STATUS_READ_ONLY == aStatus)
+       errorKey = kReadOnly;
+     else if (PROFILE_STATUS_ACCESS_DENIED == aStatus)
+       errorKey = kAccessDenied;
+-    sb->FormatStringFromName(errorKey, params, 2, getter_Copies(killMessage));
++    GetFormattedString(overrideSB, sb, errorKey, params, 2,
++                       getter_Copies(killMessage));
+ 
+-    const char16_t *titleKey = ((PROFILE_STATUS_READ_ONLY == aStatus) ||
++    const char16_t* titleKey = ((PROFILE_STATUS_READ_ONLY == aStatus) ||
+                                 (PROFILE_STATUS_ACCESS_DENIED == aStatus))
+                                    ? MOZ_UTF16("profileProblemTitle")
+                                    : MOZ_UTF16("restartTitle");
+ 
+     nsXPIDLString killTitle;
+-    sb->FormatStringFromName(titleKey, params, 1, getter_Copies(killTitle));
++    GetFormattedString(overrideSB, sb, titleKey, params, 1,
++                       getter_Copies(killTitle));
+ 
+     if (!killMessage || !killTitle)
+       return NS_ERROR_FAILURE;
+@@ -2088,7 +2191,7 @@ ProfileMissingDialog(nsINativeAppSupport* aNative)
+     sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
+     NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE);
+   
+-    NS_ConvertUTF8toUTF16 appName(gAppData->name);
++    NS_ConvertUTF8toUTF16 appName(MOZ_APP_DISPLAYNAME);
+     const char16_t* params[] = {appName.get(), appName.get()};
+   
+     nsXPIDLString missingMessage;





More information about the tor-commits mailing list