Bug 313700 - Use a bundle's Info.plist timestamp as the plug-in's last-modified date to prevent stale info in pluginreg.dat. Original patch by by Steven Michaud <smichaud@pobox.com>, r=josh; backported by me, r=smorgan. a=me for Camino 2.1 series (bug 740620) CAMINO_2_1_SECBRANCH
authorSmokey Ardisson <alqahira@ardisson.org>
Mon, 30 Apr 2012 01:38:51 -0400
branchCAMINO_2_1_SECBRANCH
changeset 35289 0f6dd57eed4c4e07221affa106f668dce2572646
parent 35288 d0c0f3cb8ba67593b229bf279463702c5c79d28b
child 35290 b66b287a2650de54f6b2a2b92f6bd456d1bcd76e
push id2038
push useralqahira@ardisson.org
push dateMon, 30 Apr 2012 05:39:30 +0000
reviewersjosh, backported, smorgan, me
bugs313700, 740620
milestone1.9.2.29pre
Bug 313700 - Use a bundle's Info.plist timestamp as the plug-in's last-modified date to prevent stale info in pluginreg.dat. Original patch by by Steven Michaud <smichaud@pobox.com>, r=josh; backported by me, r=smorgan. a=me for Camino 2.1 series (bug 740620)
modules/plugin/base/src/nsPluginHost.cpp
xpcom/io/nsILocalFileMac.idl
xpcom/io/nsLocalFileOSX.mm
--- a/modules/plugin/base/src/nsPluginHost.cpp
+++ b/modules/plugin/base/src/nsPluginHost.cpp
@@ -68,16 +68,19 @@
 #include "nsIInputStream.h"
 #include "nsIOutputStream.h"
 #include "nsIURL.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
 #include "nsIProtocolProxyService.h"
 #include "nsIStreamConverterService.h"
 #include "nsIFile.h"
+#if defined(XP_MACOSX)
+#include "nsILocalFileMac.h"
+#endif
 #include "nsIInputStream.h"
 #include "nsIIOService.h"
 #include "nsIURL.h"
 #include "nsIChannel.h"
 #include "nsISeekableStream.h"
 #include "nsNetUtil.h"
 #include "nsIProgressEventSink.h"
 #include "nsIDocument.h"
@@ -4657,17 +4660,29 @@ nsresult nsPluginHost::ScanPluginsDirect
 
     if (nsPluginsDir::IsPluginFile(dirEntry)) {
       pluginFileinDirectory * item = pluginFilesArray.AppendElement();
       if (!item)
         return NS_ERROR_OUT_OF_MEMORY;
 
       // Get file mod time
       PRInt64 fileModTime = LL_ZERO;
+#if defined(XP_MACOSX)
+    // On OS X the date of a bundle's "contents" (i.e. of its Info.plist file)
+    // is a much better guide to when it was last modified than the date of
+    // its package directory.  See bug 313700.
+    nsCOMPtr<nsILocalFileMac> localFileMac = do_QueryInterface(dirEntry);
+    if (localFileMac) {
+      localFileMac->GetBundleContentsLastModifiedTime(&fileModTime);
+    } else {
       dirEntry->GetLastModifiedTime(&fileModTime);
+    }
+#else
+      dirEntry->GetLastModifiedTime(&fileModTime);
+#endif
 
       item->mModTime = fileModTime;
       item->mFilePath = filePath;
       item->mFileName = fileName;
     }
   } // end round of up of plugin files
 
   // now sort the array by file modification time or by filename, if equal
--- a/xpcom/io/nsILocalFileMac.idl
+++ b/xpcom/io/nsILocalFileMac.idl
@@ -45,17 +45,17 @@
 %}
 
       native OSType(OSType);
       native FSSpec(FSSpec);
       native FSRef(FSRef);
 [ptr] native FSRefPtr(FSRef);
       native CFURLRef(CFURLRef);
 
-[scriptable, uuid(86D685E5-EE3F-405A-B521-446529DB82E5)]
+[scriptable, uuid(605AD84A-2834-4FE2-8280-59F40AB2BC87)]
 interface nsILocalFileMac : nsILocalFile
 {
    /**
     * initWithCFURL
     *
     * Init this object with a CFURLRef
     *
     * NOTE: Supported only for XP_MACOSX or TARGET_CARBON
@@ -205,16 +205,25 @@ interface nsILocalFileMac : nsILocalFile
    readonly attribute AString bundleDisplayName;
 
    /**
     * bundleIdentifier
     *
     * returns the identifier of the bundle
     */
    readonly attribute AUTF8String bundleIdentifier;
+
+    /**
+     * Last modified time of a bundle's contents (as opposed to its package
+     * directory).  Our convention is to make the bundle's Info.plist file
+     * stand in for the rest of its contents -- since this file contains the
+     * bundle's version information and other identifiers.  For non-bundles
+     * this is the same as lastModifiedTime.
+     */
+    readonly attribute PRInt64 bundleContentsLastModifiedTime;
 };
 
 %{C++
 extern "C"
 {
 NS_EXPORT nsresult NS_NewLocalFileWithFSRef(const FSRef* aFSRef, PRBool aFollowSymlinks, nsILocalFileMac** result);
 NS_EXPORT nsresult NS_NewLocalFileWithCFURL(const CFURLRef aURL, PRBool aFollowSymlinks, nsILocalFileMac** result);
 }
--- a/xpcom/io/nsLocalFileOSX.mm
+++ b/xpcom/io/nsLocalFileOSX.mm
@@ -1918,16 +1918,47 @@ nsLocalFile::GetBundleIdentifier(nsACStr
     ::CFRelease(urlRef);
   }
 
   return rv;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
+NS_IMETHODIMP
+nsLocalFile::GetBundleContentsLastModifiedTime(PRInt64 *aLastModTime)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  CHECK_INIT();
+  NS_ENSURE_ARG(aLastModTime);
+
+  PRBool isPackage = PR_FALSE;
+  nsresult rv = IsPackage(&isPackage);
+  if (NS_FAILED(rv) || !isPackage) {
+    return GetLastModifiedTime(aLastModTime);
+  }
+
+  nsCAutoString infoPlistPath(mPath);
+  infoPlistPath.AppendLiteral("/Contents/Info.plist");
+  PRFileInfo64 info;
+  if (PR_GetFileInfo64(infoPlistPath.get(), &info) != PR_SUCCESS) {
+    return GetLastModifiedTime(aLastModTime);
+  }
+  PRInt64 modTime = PRInt64(info.modifyTime);
+  if (modTime == 0) {
+    *aLastModTime = 0;
+  } else {
+    *aLastModTime = modTime / PRInt64(PR_USEC_PER_MSEC);
+  }
+
+  return NS_OK;
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
 #pragma mark -
 #pragma mark [Protected Methods]
 
 nsresult nsLocalFile::SetBaseURL(CFURLRef aCFURLRef)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   NS_ENSURE_ARG(aCFURLRef);