Bug 644585 - Firefox 4 cannot find plugins whose path is non-ASCII. Make nsPluginTag.mFullPath and various other "full path" members use wide strings, so that we don't have to guess (and get it wrong in a couple cases) whether it's native encoding (which is lossy on Windows) or UTF8. Also, remove support for reading older versions of the plugin registry file, since it's just a cache and doesn't contain data important to the user. r=josh
authorBenjamin Smedberg <benjamin@smedbergs.us>
Fri, 01 Apr 2011 13:28:33 -0400
changeset 64606 e61659c0f0d4505edcb6c018a38f21c830da2e26
parent 64605 da9ddc764f848048b458f9470c1d4c96037780f3
child 64607 d7fc46501527a4aeecdf3f69f908b250a305ef00
push idunknown
push userunknown
push dateunknown
reviewersjosh
bugs644585
milestone2.2a1pre
Bug 644585 - Firefox 4 cannot find plugins whose path is non-ASCII. Make nsPluginTag.mFullPath and various other "full path" members use wide strings, so that we don't have to guess (and get it wrong in a couple cases) whether it's native encoding (which is lossy on Windows) or UTF8. Also, remove support for reading older versions of the plugin registry file, since it's just a cache and doesn't contain data important to the user. r=josh
dom/plugins/PluginModuleChild.cpp
dom/plugins/PluginModuleChild.h
dom/plugins/PluginModuleParent.cpp
dom/plugins/PluginModuleParent.h
modules/plugin/base/src/PluginPRLibrary.h
modules/plugin/base/src/nsNPAPIPlugin.cpp
modules/plugin/base/src/nsPluginHost.cpp
modules/plugin/base/src/nsPluginHost.h
modules/plugin/base/src/nsPluginTags.cpp
modules/plugin/base/src/nsPluginTags.h
modules/plugin/base/src/nsPluginsDir.h
modules/plugin/base/src/nsPluginsDirDarwin.cpp
modules/plugin/base/src/nsPluginsDirUnix.cpp
modules/plugin/base/src/nsPluginsDirWin.cpp
netwerk/cache/nsDiskCacheStreams.cpp
--- a/dom/plugins/PluginModuleChild.cpp
+++ b/dom/plugins/PluginModuleChild.cpp
@@ -102,17 +102,16 @@ static bool gDelayFlashFocusReplyUntilEv
 static WindowsDllInterceptor sUser32Intercept;
 typedef BOOL (WINAPI *GetWindowInfoPtr)(HWND hwnd, PWINDOWINFO pwi);
 static GetWindowInfoPtr sGetWindowInfoPtrStub = NULL;
 static HWND sBrowserHwnd = NULL;
 #endif
 
 PluginModuleChild::PluginModuleChild()
   : mLibrary(0)
-  , mPluginFilename("")
   , mQuirks(QUIRKS_NOT_INITIALIZED)
   , mShutdownFunc(0)
   , mInitializeFunc(0)
 #if defined(OS_WIN) || defined(OS_MACOSX)
   , mGetEntryPointsFunc(0)
 #elif defined(MOZ_WIDGET_GTK2)
   , mNestedLoopTimerId(0)
 #elif defined(MOZ_WIDGET_QT)
@@ -179,21 +178,21 @@ PluginModuleChild::Init(const std::strin
     if (!mIntIdentifiers.Init()) {
        NS_ERROR("Failed to initialize int identifier hashtable!");
        return false;
     }
 
     if (!InitGraphics())
         return false;
 
-    mPluginFilename = aPluginFilename.c_str();
+    CopyUTF8toUTF16(aPluginFilename.c_str(), mPluginFilename);
     nsCOMPtr<nsILocalFile> pluginFile;
-    NS_NewNativeLocalFile(mPluginFilename,
-                          PR_TRUE,
-                          getter_AddRefs(pluginFile));
+    NS_NewLocalFile(mPluginFilename,
+                    PR_TRUE,
+                    getter_AddRefs(pluginFile));
 
     PRBool exists;
     pluginFile->Exists(&exists);
     NS_ASSERTION(exists, "plugin file ain't there");
 
     nsCOMPtr<nsIFile> pluginIfile;
     pluginIfile = do_QueryInterface(pluginFile);
 
@@ -1875,17 +1874,17 @@ PluginModuleChild::InitQuirksModes(const
         mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK;
         mQuirks |= QUIRK_FLASH_THROTTLE_WMUSER_EVENTS; 
         mQuirks |= QUIRK_FLASH_HOOK_SETLONGPTR;
         mQuirks |= QUIRK_FLASH_HOOK_GETWINDOWINFO;
         mQuirks |= QUIRK_FLASH_FIXUP_MOUSE_CAPTURE;
     }
 
     // QuickTime plugin usually loaded with audio/mpeg mimetype
-    NS_NAMED_LITERAL_CSTRING(quicktime, "npqtplugin");
+    NS_NAMED_LITERAL_STRING(quicktime, "npqtplugin");
     if (FindInReadable(quicktime, mPluginFilename)) {
       mQuirks |= QUIRK_QUICKTIME_AVOID_SETWINDOW;
     }
 #endif
 }
 
 bool
 PluginModuleChild::AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor,
--- a/dom/plugins/PluginModuleChild.h
+++ b/dom/plugins/PluginModuleChild.h
@@ -277,17 +277,17 @@ private:
 
     NS_OVERRIDE
     virtual void EnteredCxxStack();
     NS_OVERRIDE
     virtual void ExitedCxxStack();
 #endif
 
     PRLibrary* mLibrary;
-    nsCString mPluginFilename;
+    nsString mPluginFilename;
     nsCString mUserAgent;
     int mQuirks;
 
     // we get this from the plugin
     NP_PLUGINSHUTDOWN mShutdownFunc;
 #ifdef OS_LINUX
     NP_PLUGINUNIXINIT mInitializeFunc;
 #elif defined(OS_WIN) || defined(OS_MACOSX)
--- a/dom/plugins/PluginModuleParent.cpp
+++ b/dom/plugins/PluginModuleParent.cpp
@@ -78,17 +78,17 @@ struct RunnableMethodTraits<mozilla::plu
 {
     typedef mozilla::plugins::PluginModuleParent Class;
     static void RetainCallee(Class* obj) { }
     static void ReleaseCallee(Class* obj) { }
 };
 
 // static
 PluginLibrary*
-PluginModuleParent::LoadModule(const char* aFilePath)
+PluginModuleParent::LoadModule(const nsAString& aFilePath)
 {
     PLUGIN_LOG_DEBUG_FUNCTION;
 
     PRInt32 prefSecs = nsContentUtils::GetIntPref(kLaunchTimeoutPref, 0);
 
     // Block on the child process being launched and initialized.
     nsAutoPtr<PluginModuleParent> parent(new PluginModuleParent(aFilePath));
     bool launched = parent->mSubprocess->Launch(prefSecs * 1000);
@@ -100,18 +100,18 @@ PluginModuleParent::LoadModule(const cha
     parent->Open(parent->mSubprocess->GetChannel(),
                  parent->mSubprocess->GetChildProcessHandle());
 
     TimeoutChanged(kTimeoutPref, parent);
     return parent.forget();
 }
 
 
-PluginModuleParent::PluginModuleParent(const char* aFilePath)
-    : mSubprocess(new PluginProcessParent(aFilePath))
+PluginModuleParent::PluginModuleParent(const nsAString& aFilePath)
+    : mSubprocess(new PluginProcessParent(NS_ConvertUTF16toUTF8(aFilePath).get()))
     , mPluginThread(0)
     , mShutdown(false)
     , mClearSiteDataSupported(false)
     , mGetSitesWithDataSupported(false)
     , mNPNIface(NULL)
     , mPlugin(NULL)
     , mProcessStartTime(time(NULL))
     , mTaskFactory(this)
--- a/dom/plugins/PluginModuleParent.h
+++ b/dom/plugins/PluginModuleParent.h
@@ -101,33 +101,33 @@ protected:
                          const InfallibleTArray<nsCString>& aNames,
                          const InfallibleTArray<nsCString>& aValues,
                          NPError* rv);
 
     virtual bool
     DeallocPPluginInstance(PPluginInstanceParent* aActor);
 
 public:
-    PluginModuleParent(const char* aFilePath);
+    PluginModuleParent(const nsAString& aFilePath);
     virtual ~PluginModuleParent();
 
     NS_OVERRIDE virtual void SetPlugin(nsNPAPIPlugin* plugin)
     {
         mPlugin = plugin;
     }
 
     NS_OVERRIDE virtual void ActorDestroy(ActorDestroyReason why);
 
     /**
      * LoadModule
      *
      * This may or may not launch a plugin child process,
      * and may or may not be very expensive.
      */
-    static PluginLibrary* LoadModule(const char* aFilePath);
+    static PluginLibrary* LoadModule(const nsAString& aFilePath);
 
     const NPNetscapeFuncs* GetNetscapeFuncs() {
         return mNPNIface;
     }
 
     PluginProcessParent* Process() const { return mSubprocess; }
     base::ProcessHandle ChildProcessHandle() { return mSubprocess->GetChildProcessHandle(); }
 
--- a/modules/plugin/base/src/PluginPRLibrary.h
+++ b/modules/plugin/base/src/PluginPRLibrary.h
@@ -43,17 +43,17 @@
 #include "nsNPAPIPlugin.h"
 #include "npfunctions.h"
 
 namespace mozilla {
 
 class PluginPRLibrary : public PluginLibrary
 {
 public:
-    PluginPRLibrary(const char* aFilePath, PRLibrary* aLibrary) :
+    PluginPRLibrary(const nsAString& aFilePath, PRLibrary* aLibrary) :
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
         mNP_Initialize(nsnull),
 #else
         mNP_Initialize(nsnull),
 #endif
         mNP_Shutdown(nsnull),
         mNP_GetMIMEDescription(nsnull),
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
--- a/modules/plugin/base/src/nsNPAPIPlugin.cpp
+++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp
@@ -374,17 +374,17 @@ nsNPAPIPlugin::RunPluginOOP(const nsPlug
     return PR_FALSE;
   }
 
   // Get per-library whitelist/blacklist pref string
   // "dom.ipc.plugins.enabled.filename.dll" and fall back to the default value
   // of "dom.ipc.plugins.enabled"
   // The "filename.dll" part can contain shell wildcard pattern
 
-  nsCAutoString prefFile(aPluginTag->mFullPath.get());
+  NS_ConvertUTF16toUTF8 prefFile(aPluginTag->mFullPath);
   PRInt32 slashPos = prefFile.RFindCharInSet("/\\");
   if (kNotFound == slashPos)
     return PR_FALSE;
   prefFile.Cut(0, slashPos + 1);
   ToLowerCase(prefFile);
 
 #ifdef XP_MACOSX
 #if defined(__i386__)
@@ -467,20 +467,20 @@ inline PluginLibrary*
 GetNewPluginLibrary(nsPluginTag *aPluginTag)
 {
   if (!aPluginTag) {
     return nsnull;
   }
 
 #ifdef MOZ_IPC
   if (nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
-    return PluginModuleParent::LoadModule(aPluginTag->mFullPath.get());
+    return PluginModuleParent::LoadModule(aPluginTag->mFullPath);
   }
 #endif
-  return new PluginPRLibrary(aPluginTag->mFullPath.get(), aPluginTag->mLibrary);
+  return new PluginPRLibrary(aPluginTag->mFullPath, aPluginTag->mLibrary);
 }
 
 // Creates an nsNPAPIPlugin object. One nsNPAPIPlugin object exists per plugin (not instance).
 nsresult
 nsNPAPIPlugin::CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult)
 {
   *aResult = nsnull;
 
--- a/modules/plugin/base/src/nsPluginHost.cpp
+++ b/modules/plugin/base/src/nsPluginHost.cpp
@@ -175,35 +175,18 @@ using mozilla::TimeStamp;
     }                                                                \
   }
 
 // this is the name of the directory which will be created
 // to cache temporary files.
 #define kPluginTmpDirName NS_LITERAL_CSTRING("plugtmp")
 
 // Version of cached plugin info
-// 0.01 first implementation
-// 0.02 added caching of CanUnload to fix bug 105935
-// 0.03 changed name, description and mime desc from string to bytes, bug 108246
-// 0.04 added new mime entry point on Mac, bug 113464
-// 0.05 added new entry point check for the default plugin, bug 132430
-// 0.06 strip off suffixes in mime description strings, bug 53895
-// 0.07 changed nsIRegistry to flat file support for caching plugins info
-// 0.08 mime entry point on MachO, bug 137535
-// 0.09 the file encoding is changed to UTF-8, bug 420285
-// 0.10 added plugin versions on appropriate platforms, bug 427743
-// 0.11 file name and full path fields now store expected values on all platforms, bug 488181
-// 0.12 force refresh due to quicktime pdf claim fix, bug 611197
-// 0.13 add architecture and list of invalid plugins, bug 616271
-// 0.14 force refresh due to locale comparison fix, bug 611296
-// 0.15 force refresh due to bug in reading Java plist MIME data, bug 638171
-// The current plugin registry version (and the maximum version we know how to read)
-static const char *kPluginRegistryVersion = "0.15";
-// The minimum registry version we know how to read
-static const char *kMinimumRegistryVersion = "0.9";
+// The current plugin registry version (and the only version we know how to read)
+static const char *kPluginRegistryVersion = "0.16";
 
 static NS_DEFINE_IID(kIPluginTagInfoIID, NS_IPLUGINTAGINFO_IID);
 static const char kDirectoryServiceContractID[] = "@mozilla.org/file/directory_service;1";
 
 // Registry keys for caching plugin info
 static const char kPluginsRootKey[] = "software/plugins";
 static const char kPluginsNameKey[] = "name";
 static const char kPluginsDescKey[] = "description";
@@ -236,17 +219,17 @@ PRLogModuleInfo* nsPluginLogging::gPlugi
 PRBool gSkipPluginSafeCalls = PR_TRUE;
 #endif
 
 nsIFile *nsPluginHost::sPluginTempDir;
 nsPluginHost *nsPluginHost::sInst;
 
 NS_IMPL_ISUPPORTS0(nsInvalidPluginTag)
 
-nsInvalidPluginTag::nsInvalidPluginTag(const char* aFullPath, PRInt64 aLastModifiedTime)
+nsInvalidPluginTag::nsInvalidPluginTag(const nsAString& aFullPath, PRInt64 aLastModifiedTime)
 : mFullPath(aFullPath),
   mLastModifiedTime(aLastModifiedTime),
   mSeen(false)
 {
   
 }
 
 nsInvalidPluginTag::~nsInvalidPluginTag()
@@ -1534,17 +1517,17 @@ public:
 
   NS_METHOD GetFilename(nsAString& aFilename)
   {
     PRBool bShowPath;
     nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
     if (prefService &&
         NS_SUCCEEDED(prefService->GetBoolPref("plugin.expose_full_path", &bShowPath)) &&
         bShowPath) {
-      CopyUTF8toUTF16(mPluginTag.mFullPath, aFilename);
+      aFilename = mPluginTag.mFullPath;
     } else {
       CopyUTF8toUTF16(mPluginTag.mFileName, aFilename);
     }
 
     return NS_OK;
   }
 
   NS_METHOD GetVersion(nsAString& aVersion)
@@ -1714,91 +1697,53 @@ nsPluginHost::FindPluginEnabledForExtens
 
       plugins = plugins->mNext;
     }
   }
 
   return nsnull;
 }
 
-static nsresult ConvertToNative(nsIUnicodeEncoder *aEncoder,
-                                const nsACString& aUTF8String,
-                                nsACString& aNativeString)
-{
-  NS_ConvertUTF8toUTF16 utf16(aUTF8String);
-  PRInt32 len = utf16.Length();
-  PRInt32 outLen;
-  nsresult rv = aEncoder->GetMaxLength(utf16.get(), len, &outLen);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (!EnsureStringLength(aNativeString, outLen))
-    return NS_ERROR_OUT_OF_MEMORY;
-  rv = aEncoder->Convert(utf16.get(), &len,
-                         aNativeString.BeginWriting(), &outLen);
-  NS_ENSURE_SUCCESS(rv, rv);
-  aNativeString.SetLength(outLen);
-  return NS_OK;
-}
-
 static nsresult CreateNPAPIPlugin(nsPluginTag *aPluginTag,
                                   nsNPAPIPlugin **aOutNPAPIPlugin)
 {
   // If this is an in-process plugin we'll need to load it here if we haven't already.
 #ifdef MOZ_IPC
   if (!nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
 #else
   if (!aPluginTag->mLibrary) {
 #endif
     if (aPluginTag->mFullPath.IsEmpty())
       return NS_ERROR_FAILURE;
     nsCOMPtr<nsILocalFile> file = do_CreateInstance("@mozilla.org/file/local;1");
-    file->InitWithPath(NS_ConvertUTF8toUTF16(aPluginTag->mFullPath));
+    file->InitWithPath(aPluginTag->mFullPath);
     nsPluginFile pluginFile(file);
     PRLibrary* pluginLibrary = NULL;
 
     if (NS_FAILED(pluginFile.LoadPlugin(&pluginLibrary)) || !pluginLibrary)
       return NS_ERROR_FAILURE;
 
     aPluginTag->mLibrary = pluginLibrary;
   }
 
   nsresult rv;
   nsCOMPtr <nsIPlatformCharset> pcs =
     do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCAutoString charset;
-  rv = pcs->GetCharset(kPlatformCharsetSel_FileName, charset);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCAutoString fullPath;
-  if (!charset.LowerCaseEqualsLiteral("utf-8")) {
-    nsCOMPtr<nsIUnicodeEncoder> encoder;
-    nsCOMPtr<nsICharsetConverterManager> ccm =
-      do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = ccm->GetUnicodeEncoderRaw(charset.get(), getter_AddRefs(encoder));
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = ConvertToNative(encoder, aPluginTag->mFullPath, fullPath);
-    NS_ENSURE_SUCCESS(rv, rv);
-  } else {
-    fullPath = aPluginTag->mFullPath;
-  }
+  rv = nsNPAPIPlugin::CreatePlugin(aPluginTag, aOutNPAPIPlugin);
 
 #if defined(XP_MACOSX) && !defined(__LP64__)
   short appRefNum = ::CurResFile();
   nsCOMPtr<nsILocalFile> pluginPath;
-  NS_NewNativeLocalFile(nsDependentCString(fullPath.get()), PR_TRUE,
-                        getter_AddRefs(pluginPath));
+  NS_NewLocalFile(aPluginTag->mFullPath, PR_TRUE,
+                  getter_AddRefs(pluginPath));
   nsPluginFile pluginFile(pluginPath);
   short pluginRefNum = pluginFile.OpenPluginResource();
-#endif
-
-  rv = nsNPAPIPlugin::CreatePlugin(aPluginTag, aOutNPAPIPlugin);
-
-#if defined(XP_MACOSX) && !defined(__LP64__)
+
   if (NS_SUCCEEDED(rv))
     (*aOutNPAPIPlugin)->SetPluginRefNum(pluginRefNum);
   else if (pluginRefNum > 0)
     ::CloseResFile(pluginRefNum);
   ::UseResFile(appRefNum);
 #endif
 
   return rv;
@@ -2223,19 +2168,18 @@ nsresult nsPluginHost::ScanPluginsDirect
   for (PRUint32 i = 0; i < pluginFilesArray.Length(); i++) {
     pluginFileinDirectory &pfd = pluginFilesArray[i];
     nsCOMPtr <nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
     nsCOMPtr <nsILocalFile> localfile = do_QueryInterface(file);
     localfile->InitWithPath(pfd.mFilePath);
     PRInt64 fileModTime = pfd.mModTime;
 
     // Look for it in our cache
-    NS_ConvertUTF16toUTF8 filePath(pfd.mFilePath);
     nsRefPtr<nsPluginTag> pluginTag;
-    RemoveCachedPluginsInfo(filePath.get(),
+    RemoveCachedPluginsInfo(pfd.mFilePath,
                             getter_AddRefs(pluginTag));
 
     PRBool enabled = PR_TRUE;
     PRBool seenBefore = PR_FALSE;
     if (pluginTag) {
       seenBefore = PR_TRUE;
       // If plugin changed, delete cachedPluginTag and don't use cache
       if (LL_NE(fileModTime, pluginTag->mLastModifiedTime)) {
@@ -2273,17 +2217,17 @@ nsresult nsPluginHost::ScanPluginsDirect
         continue;
       }
     }
     
     bool isKnownInvalidPlugin = false;
     for (nsRefPtr<nsInvalidPluginTag> invalidPlugins = mInvalidPlugins;
          invalidPlugins; invalidPlugins = invalidPlugins->mNext) {
       // If already marked as invalid, ignore it
-      if (invalidPlugins->mFullPath.Equals(filePath.get()) &&
+      if (invalidPlugins->mFullPath.Equals(pfd.mFilePath) &&
           invalidPlugins->mLastModifiedTime == fileModTime) {
         if (aCreatePluginList) {
           invalidPlugins->mSeen = true;
         }
         isKnownInvalidPlugin = true;
         break;
       }
     }
@@ -2297,17 +2241,17 @@ nsresult nsPluginHost::ScanPluginsDirect
 
       // create a tag describing this plugin.
       PRLibrary *library = nsnull;
       nsPluginInfo info;
       memset(&info, 0, sizeof(info));
       nsresult res = pluginFile.GetPluginInfo(info, &library);
       // if we don't have mime type don't proceed, this is not a plugin
       if (NS_FAILED(res) || !info.fMimeTypeArray) {
-        nsRefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(filePath.get(),
+        nsRefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(pfd.mFilePath,
                                                                          fileModTime);
         pluginFile.FreePluginInfo(info);
         
         if (aCreatePluginList) {
           invalidTag->mSeen = true;
         }
         invalidTag->mNext = mInvalidPlugins;
         if (mInvalidPlugins) {
@@ -2756,23 +2700,23 @@ nsPluginHost::WritePluginInfo()
     for (nsPluginTag *tag = taglist[i]; tag; tag=tag->mNext) {
       // from mCachedPlugins list write down only unwanted plugins
       if ((taglist[i] == mCachedPlugins) && !tag->HasFlag(NS_PLUGIN_FLAG_UNWANTED))
         continue;
       // store each plugin info into the registry
       // filename & fullpath are on separate line
       // because they can contain field delimiter char
       PR_fprintf(fd, "%s%c%c\n%s%c%c\n%s%c%c\n",
-        (!tag->mFileName.IsEmpty() ? tag->mFileName.get() : ""),
+        tag->mFileName.get(),
         PLUGIN_REGISTRY_FIELD_DELIMITER,
         PLUGIN_REGISTRY_END_OF_LINE_MARKER,
-        (!tag->mFullPath.IsEmpty() ? tag->mFullPath.get() : ""),
+        tag->mFullPath.get(),
         PLUGIN_REGISTRY_FIELD_DELIMITER,
         PLUGIN_REGISTRY_END_OF_LINE_MARKER,
-        (!tag->mVersion.IsEmpty() ? tag->mVersion.get() : ""),
+        tag->mVersion.get(),
         PLUGIN_REGISTRY_FIELD_DELIMITER,
         PLUGIN_REGISTRY_END_OF_LINE_MARKER);
 
       // lastModifiedTimeStamp|canUnload|tag->mFlags
       PR_fprintf(fd, "%lld%c%d%c%lu%c%c\n",
         tag->mLastModifiedTime,
         PLUGIN_REGISTRY_FIELD_DELIMITER,
         tag->mCanUnloadLibrary,
@@ -2819,17 +2763,17 @@ nsPluginHost::WritePluginInfo()
   }
   
   PR_fprintf(fd, "\n[INVALID]\n");
   
   nsRefPtr<nsInvalidPluginTag> invalidPlugins = mInvalidPlugins;
   while (invalidPlugins) {
     // fullPath
     PR_fprintf(fd, "%s%c%c\n",
-      (!invalidPlugins->mFullPath.IsEmpty() ? invalidPlugins->mFullPath.get() : ""),
+      NS_ConvertUTF16toUTF8(invalidPlugins->mFullPath).get(),
       PLUGIN_REGISTRY_FIELD_DELIMITER,
       PLUGIN_REGISTRY_END_OF_LINE_MARKER);
 
     // lastModifiedTimeStamp
     PR_fprintf(fd, "%lld%c%c\n",
       invalidPlugins->mLastModifiedTime,
       PLUGIN_REGISTRY_FIELD_DELIMITER,
       PLUGIN_REGISTRY_END_OF_LINE_MARKER);
@@ -2926,124 +2870,81 @@ nsPluginHost::ReadPluginInfo()
   if (2 != reader.ParseLine(values, 2))
     return rv;
 
   // VersionLiteral
   if (PL_strcmp(values[0], "Version"))
     return rv;
 
   // kPluginRegistryVersion
-  PRInt32 vdiff = NS_CompareVersions(values[1], kPluginRegistryVersion);
-  // If this is a registry from some future version then don't attempt to read it
-  if (vdiff > 0)
-    return rv;
-  // If this is a registry from before the minimum then don't attempt to read it
-  if (NS_CompareVersions(values[1], kMinimumRegistryVersion) < 0)
+  if (!strcmp(values[1], kPluginRegistryVersion))
     return rv;
 
-  // Registry v0.10 and upwards includes the plugin version field
-  PRBool regHasVersion = NS_CompareVersions(values[1], "0.10") >= 0;
-
-  // Registry v0.13 and upwards includes the architecture
-  if (NS_CompareVersions(values[1], "0.13") >= 0) {
-    char* archValues[6];
+  char* archValues[6];
     
-    if (!reader.NextLine()) {
-      return rv;
-    }
+  if (!reader.NextLine()) {
+    return rv;
+  }
     
-    // ArchLiteral, Architecture
-    if (2 != reader.ParseLine(archValues, 2)) {
-      return rv;
-    }
+  // ArchLiteral, Architecture
+  if (2 != reader.ParseLine(archValues, 2)) {
+    return rv;
+  }
       
-    // ArchLiteral
-    if (PL_strcmp(archValues[0], "Arch")) {
-      return rv;
-    }
+  // ArchLiteral
+  if (PL_strcmp(archValues[0], "Arch")) {
+    return rv;
+  }
       
-    nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
-    if (!runtime) {
-      return rv;
-    }
+  nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
+  if (!runtime) {
+    return rv;
+  }
       
-    nsCAutoString arch;
-    if (NS_FAILED(runtime->GetXPCOMABI(arch))) {
-      return rv;
-    }
+  nsCAutoString arch;
+  if (NS_FAILED(runtime->GetXPCOMABI(arch))) {
+    return rv;
+  }
       
-    // If this is a registry from a different architecture then don't attempt to read it
-    if (PL_strcmp(archValues[1], arch.get())) {
-      return rv;
-    }
+  // If this is a registry from a different architecture then don't attempt to read it
+  if (PL_strcmp(archValues[1], arch.get())) {
+    return rv;
   }
   
-  // Registry v0.13 and upwards includes the list of invalid plugins
-  bool hasInvalidPlugins = (NS_CompareVersions(values[1], "0.13") >= 0);
-
   if (!ReadSectionHeader(reader, "PLUGINS"))
     return rv;
 
-#if defined(XP_MACOSX)
-  PRBool hasFullPathInFileNameField = PR_FALSE;
-#else
-  PRBool hasFullPathInFileNameField = (NS_CompareVersions(values[1], "0.11") < 0);
-#endif
-
   while (reader.NextLine()) {
     const char *filename;
     const char *fullpath;
     nsCAutoString derivedFileName;
     
-    if (hasInvalidPlugins && *reader.LinePtr() == '[') {
+    if (*reader.LinePtr() == '[') {
       break;
     }
     
-    if (hasFullPathInFileNameField) {
-      fullpath = reader.LinePtr();
-      if (!reader.NextLine())
-        return rv;
-      // try to derive a file name from the full path
-      if (fullpath) {
-        nsCOMPtr<nsILocalFile> file = do_CreateInstance("@mozilla.org/file/local;1");
-        file->InitWithNativePath(nsDependentCString(fullpath));
-        file->GetNativeLeafName(derivedFileName);
-        filename = derivedFileName.get();
-      } else {
-        filename = NULL;
-      }
-
-      // skip the next line, useless in this version
-      if (!reader.NextLine())
-        return rv;
-    } else {
-      filename = reader.LinePtr();
-      if (!reader.NextLine())
-        return rv;
-
-      fullpath = reader.LinePtr();
-      if (!reader.NextLine())
-        return rv;
-    }
+    filename = reader.LinePtr();
+    if (!reader.NextLine())
+      return rv;
+
+    fullpath = reader.LinePtr();
+    if (!reader.NextLine())
+      return rv;
 
     const char *version;
-    if (regHasVersion) {
-      version = reader.LinePtr();
-      if (!reader.NextLine())
-        return rv;
-    } else {
-      version = "0";
-    }
+    version = reader.LinePtr();
+    if (!reader.NextLine())
+      return rv;
 
     // lastModifiedTimeStamp|canUnload|tag.mFlag
     if (reader.ParseLine(values, 3) != 3)
       return rv;
 
     // If this is an old plugin registry mark this plugin tag to be refreshed
-    PRInt64 lastmod = (vdiff == 0) ? nsCRT::atoll(values[0]) : -1;
+    PRInt64 lastmod = nsCRT::atoll(values[0]);
     PRBool canunload = atoi(values[1]);
     PRUint32 tagflag = atoi(values[2]);
     if (!reader.NextLine())
       return rv;
 
     const char *description = reader.LinePtr();
     if (!reader.NextLine())
       return rv;
@@ -3089,17 +2990,17 @@ nsPluginHost::ReadPluginInfo()
         delete [] heapalloced;
       }
       return rv;
     }
 
     nsRefPtr<nsPluginTag> tag = new nsPluginTag(name,
       description,
       filename,
-      fullpath,
+      NS_ConvertUTF8toUTF16(fullpath),
       version,
       (const char* const*)mimetypes,
       (const char* const*)mimedescriptions,
       (const char* const*)extensions,
       mimetypecount, lastmod, canunload, PR_TRUE);
     if (heapalloced)
       delete [] heapalloced;
 
@@ -3109,44 +3010,44 @@ nsPluginHost::ReadPluginInfo()
     // Mark plugin as loaded from cache
     tag->Mark(tagflag | NS_PLUGIN_FLAG_FROMCACHE);
     PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
       ("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->mFileName.get()));
     tag->mNext = mCachedPlugins;
     mCachedPlugins = tag;
   }
   
-  if (hasInvalidPlugins) {
-    if (!ReadSectionHeader(reader, "INVALID")) {
+  if (!ReadSectionHeader(reader, "INVALID")) {
+    return rv;
+  }
+
+  while (reader.NextLine()) {
+    const char *fullpath = reader.LinePtr();
+    if (!reader.NextLine()) {
       return rv;
     }
-
-    while (reader.NextLine()) {
-      const char *fullpath = reader.LinePtr();
-      if (!reader.NextLine()) {
-        return rv;
-      }
       
-      const char *lastModifiedTimeStamp = reader.LinePtr();
-      PRInt64 lastmod = (vdiff == 0) ? nsCRT::atoll(lastModifiedTimeStamp) : -1;
+    const char *lastModifiedTimeStamp = reader.LinePtr();
+    PRInt64 lastmod = nsCRT::atoll(lastModifiedTimeStamp);
       
-      nsRefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(fullpath, lastmod);
-      
-      invalidTag->mNext = mInvalidPlugins;
-      if (mInvalidPlugins) {
-        mInvalidPlugins->mPrev = invalidTag;
-      }
-      mInvalidPlugins = invalidTag;
+    nsRefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(NS_ConvertUTF8toUTF16(fullpath),
+                                                                     lastmod);
+
+    invalidTag->mNext = mInvalidPlugins;
+    if (mInvalidPlugins) {
+      mInvalidPlugins->mPrev = invalidTag;
     }
+    mInvalidPlugins = invalidTag;
   }
+
   return NS_OK;
 }
 
 void
-nsPluginHost::RemoveCachedPluginsInfo(const char *filePath, nsPluginTag **result)
+nsPluginHost::RemoveCachedPluginsInfo(const nsAString& filePath, nsPluginTag **result)
 {
   nsRefPtr<nsPluginTag> prev;
   nsRefPtr<nsPluginTag> tag = mCachedPlugins;
   while (tag)
   {
     if (tag->mFullPath.Equals(filePath)) {
       // Found it. Remove it from our list
       if (prev)
--- a/modules/plugin/base/src/nsPluginHost.h
+++ b/modules/plugin/base/src/nsPluginHost.h
@@ -71,22 +71,22 @@ class nsIChannel;
 
 #if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
 #define MAC_CARBON_PLUGINS
 #endif
 
 class nsInvalidPluginTag : public nsISupports
 {
 public:
-  nsInvalidPluginTag(const char* aFullPath, PRInt64 aLastModifiedTime = 0);
+  nsInvalidPluginTag(const nsAString& aFullPath, PRInt64 aLastModifiedTime = 0);
   virtual ~nsInvalidPluginTag();
   
   NS_DECL_ISUPPORTS
   
-  nsCString   mFullPath;
+  nsString    mFullPath;
   PRInt64     mLastModifiedTime;
   bool        mSeen;
   
   nsRefPtr<nsInvalidPluginTag> mPrev;
   nsRefPtr<nsInvalidPluginTag> mNext;
 };
 
 class nsPluginHost : public nsIPluginHost,
@@ -252,17 +252,17 @@ private:
   // Stores all plugins info into the registry
   nsresult WritePluginInfo();
 
   // Loads all cached plugins info into mCachedPlugins
   nsresult ReadPluginInfo();
 
   // Given a file path, returns the plugins info from our cache
   // and removes it from the cache.
-  void RemoveCachedPluginsInfo(const char *filePath,
+  void RemoveCachedPluginsInfo(const nsAString& filePath,
                                nsPluginTag **result);
 
   // Checks to see if a tag object is in our list of live tags.
   PRBool IsLiveTag(nsIPluginTag* tag);
 
   // Checks our list of live tags for an equivalent tag.
   nsPluginTag* HaveSamePlugin(nsPluginTag * aPluginTag);
 
--- a/modules/plugin/base/src/nsPluginTags.cpp
+++ b/modules/plugin/base/src/nsPluginTags.cpp
@@ -197,17 +197,17 @@ mFlags(NS_PLUGIN_FLAG_ENABLED)
   RemoveJavaSentinel(javaSentinelVariant);
 
   EnsureMembersAreUTF8();
 }
 
 nsPluginTag::nsPluginTag(const char* aName,
                          const char* aDescription,
                          const char* aFileName,
-                         const char* aFullPath,
+                         const nsAString& aFullPath,
                          const char* aVersion,
                          const char* const* aMimeTypes,
                          const char* const* aMimeDescriptions,
                          const char* const* aExtensions,
                          PRInt32 aVariants,
                          PRInt64 aLastModifiedTime,
                          PRBool aCanUnload,
                          PRBool aArgsAreUTF8)
@@ -315,17 +315,16 @@ nsresult nsPluginTag::EnsureMembersAreUT
   nsCAutoString charset;
   rv = pcs->GetCharset(kPlatformCharsetSel_FileName, charset);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!charset.LowerCaseEqualsLiteral("utf-8")) {
     rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
     NS_ENSURE_SUCCESS(rv, rv);
     
     ConvertToUTF8(decoder, mFileName);
-    ConvertToUTF8(decoder, mFullPath);
   }
   
   // The description of the plug-in and the various MIME type descriptions
   // should be encoded in the standard plain text file encoding for this system.
   // XXX should we add kPlatformCharsetSel_PluginResource?
   rv = pcs->GetCharset(kPlatformCharsetSel_PlainTextInFile, charset);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!charset.LowerCaseEqualsLiteral("utf-8")) {
@@ -359,17 +358,17 @@ nsPluginTag::GetFilename(nsACString& aFi
 {
   aFileName = mFileName;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPluginTag::GetFullpath(nsACString& aFullPath)
 {
-  aFullPath = mFullPath;
+  CopyUTF16toUTF8(mFullPath, aFullPath);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPluginTag::GetVersion(nsACString& aVersion)
 {
   aVersion = mVersion;
   return NS_OK;
--- a/modules/plugin/base/src/nsPluginTags.h
+++ b/modules/plugin/base/src/nsPluginTags.h
@@ -74,17 +74,17 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPLUGINTAG
   
   nsPluginTag(nsPluginTag* aPluginTag);
   nsPluginTag(nsPluginInfo* aPluginInfo);
   nsPluginTag(const char* aName,
               const char* aDescription,
               const char* aFileName,
-              const char* aFullPath,
+              const nsAString& aFullPath,
               const char* aVersion,
               const char* const* aMimeTypes,
               const char* const* aMimeDescriptions,
               const char* const* aExtensions,
               PRInt32 aVariants,
               PRInt64 aLastModifiedTime = 0,
               PRBool aCanUnload = PR_TRUE,
               PRBool aArgsAreUTF8 = PR_FALSE);
@@ -116,17 +116,17 @@ public:
   char          **mExtensionsArray;
   PRLibrary     *mLibrary;
   nsRefPtr<nsNPAPIPlugin> mEntryPoint;
   PRPackedBool  mCanUnloadLibrary;
   PRPackedBool  mIsJavaPlugin;
   PRPackedBool  mIsNPRuntimeEnabledJavaPlugin;
   PRPackedBool  mIsFlashPlugin;
   nsCString     mFileName; // UTF-8
-  nsCString     mFullPath; // UTF-8
+  nsString      mFullPath;
   nsCString     mVersion;  // UTF-8
   PRInt64       mLastModifiedTime;
 private:
   PRUint32      mFlags;
   
   nsresult EnsureMembersAreUTF8();
 };
 
--- a/modules/plugin/base/src/nsPluginsDir.h
+++ b/modules/plugin/base/src/nsPluginsDir.h
@@ -59,17 +59,17 @@ struct PRLibrary;
 struct nsPluginInfo {
 	char* fName;				// name of the plugin
 	char* fDescription;			// etc.
 	PRUint32 fVariantCount;
 	char** fMimeTypeArray;
 	char** fMimeDescriptionArray;
 	char** fExtensionArray;
 	char* fFileName;
-	char* fFullPath;
+	PRUnichar* fFullPath;
 	char* fVersion;
 #ifdef XP_MACOSX
   PRBool fBundle;
 #endif
 };
 
 /**
  * Provides cross-platform access to a plugin file. Deals with reading
--- a/modules/plugin/base/src/nsPluginsDirDarwin.cpp
+++ b/modules/plugin/base/src/nsPluginsDirDarwin.cpp
@@ -513,17 +513,21 @@ nsresult nsPluginFile::GetPluginInfo(nsP
 
   // Try to get a bundle reference.
   nsCAutoString path;
   if (NS_FAILED(rv = mPlugin->GetNativePath(path)))
     return rv;
   CFBundleRef bundle = getPluginBundle(path.get());
 
   // fill in full path
-  info.fFullPath = PL_strdup(path.get());
+  nsAutoString wpath;
+  rv = mPlugin->GetPath(wpath);
+  if (NS_FAILED(rv))
+    return rv;
+  info.fFullPath = ToNewUnicode(wpath);
 
   // fill in file name
   nsCAutoString fileName;
   if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName)))
     return rv;
   info.fFileName = PL_strdup(fileName.get());
 
   // Get fBundle
--- a/modules/plugin/base/src/nsPluginsDirUnix.cpp
+++ b/modules/plugin/base/src/nsPluginsDirUnix.cpp
@@ -363,20 +363,20 @@ nsresult nsPluginFile::GetPluginInfo(nsP
         return NS_ERROR_FAILURE;
     }
 
     rv = ParsePluginMimeDescription(mimedescr, info);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
-    nsCAutoString path;
-    if (NS_FAILED(rv = mPlugin->GetNativePath(path)))
+    nsAutoString path;
+    if (NS_FAILED(rv = mPlugin->GetPath(path)))
         return rv;
-    info.fFullPath = PL_strdup(path.get());
+    info.fFullPath = ToNewUnicode(path);
 
     nsCAutoString fileName;
     if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName)))
         return rv;
     info.fFileName = PL_strdup(fileName.get());
 
     NP_GetValueFunc npGetValue = (NP_GetValueFunc)PR_FindFunctionSymbol(pLibrary, "NP_GetValue");
     if (!npGetValue) {
@@ -422,18 +422,17 @@ nsresult nsPluginFile::FreePluginInfo(ns
         if (info.fExtensionArray[i] != nsnull)
             PL_strfree(info.fExtensionArray[i]);
     }
 
     PR_FREEIF(info.fMimeTypeArray);
     PR_FREEIF(info.fMimeDescriptionArray);
     PR_FREEIF(info.fExtensionArray);
 
-    if (info.fFullPath != nsnull)
-        PL_strfree(info.fFullPath);
+    NS_Free(info.fFullPath);
 
     if (info.fFileName != nsnull)
         PL_strfree(info.fFileName);
 
     if (info.fVersion != nsnull)
         PL_strfree(info.fVersion);
 
     return NS_OK;
--- a/modules/plugin/base/src/nsPluginsDirWin.cpp
+++ b/modules/plugin/base/src/nsPluginsDirWin.cpp
@@ -372,17 +372,17 @@ nsresult nsPluginFile::GetPluginInfo(nsP
     char *mimeType = GetKeyValue(verbuf, L"MIMEType", lang, cp);
     char *mimeDescription = GetKeyValue(verbuf, L"FileOpenName", lang, cp);
     char *extensions = GetKeyValue(verbuf, L"FileExtents", lang, cp);
 
     info.fVariantCount = CalculateVariantCount(mimeType);
     info.fMimeTypeArray = MakeStringArray(info.fVariantCount, mimeType);
     info.fMimeDescriptionArray = MakeStringArray(info.fVariantCount, mimeDescription);
     info.fExtensionArray = MakeStringArray(info.fVariantCount, extensions);
-    info.fFullPath = PL_strdup(NS_ConvertUTF16toUTF8(fullPath).get());
+    info.fFullPath = ToNewUnicode(fullPath);
     info.fFileName = PL_strdup(NS_ConvertUTF16toUTF8(fileName).get());
     info.fVersion = GetVersion(verbuf);
 
     PL_strfree(mimeType);
     PL_strfree(mimeDescription);
     PL_strfree(extensions);
   }
   else {
@@ -407,17 +407,17 @@ nsresult nsPluginFile::FreePluginInfo(ns
 
   if (info.fMimeDescriptionArray)
     FreeStringArray(info.fVariantCount, info.fMimeDescriptionArray);
 
   if (info.fExtensionArray)
     FreeStringArray(info.fVariantCount, info.fExtensionArray);
 
   if (info.fFullPath)
-    PL_strfree(info.fFullPath);
+    NS_Free(info.fFullPath);
 
   if (info.fFileName)
     PL_strfree(info.fFileName);
 
   if (info.fVersion)
     PR_smprintf_free(info.fVersion);
 
   ZeroMemory((void *)&info, sizeof(info));
--- a/netwerk/cache/nsDiskCacheStreams.cpp
+++ b/netwerk/cache/nsDiskCacheStreams.cpp
@@ -752,19 +752,19 @@ nsDiskCacheStreamIO::FlushBufferToFile()
             if (NS_FAILED(rv))  return rv;
         }
         record->SetDataFileGeneration(mBinding->mGeneration);
         
         // allocate file
         rv = OpenCacheFile(PR_RDWR | PR_CREATE_FILE, &mFD);
         if (NS_FAILED(rv))  return rv;
 
+#if 0
         PRInt64 dataSize = mBinding->mCacheEntry->PredictedDataSize();
 // Appears to cause bug 617123?  Disabled for now.
-#if 0
         if (dataSize != -1)
             mozilla::fallocate(mFD, PR_MIN(dataSize, kPreallocateLimit));
 #endif
     }
     
     // write buffer
     PRInt32 bytesWritten = PR_Write(mFD, mBuffer, mBufEnd);
     if (PRUint32(bytesWritten) != mBufEnd) {