Bug 581518: Make Mac OS X impl of nsLocalFile::SetPersistentDescriptor behave like it did previosly, supporting aliases. r=benwa
authorJosh Aas <joshmoz@gmail.com>
Sun, 25 Jul 2010 23:49:28 -0400
changeset 48198 3559a37d183fd192c29e67e3120f9983bc843340
parent 48197 dc4f4587d5482dbbaab2bc9466b55c938a53f05b
child 48199 5cda23bbfc29e49822a8d01b2c7876fd064bc32a
push id14619
push userjosh@mozilla.com
push dateMon, 26 Jul 2010 03:50:00 +0000
treeherdermozilla-central@3559a37d183f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbenwa
bugs581518
milestone2.0b3pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 581518: Make Mac OS X impl of nsLocalFile::SetPersistentDescriptor behave like it did previosly, supporting aliases. r=benwa
xpcom/io/nsLocalFileUnix.cpp
--- a/xpcom/io/nsLocalFileUnix.cpp
+++ b/xpcom/io/nsLocalFileUnix.cpp
@@ -90,16 +90,20 @@
 #ifdef MOZ_WIDGET_GTK2
 #include "nsIGIOService.h"
 #include "nsIGnomeVFSService.h"
 #endif
 
 #ifdef XP_MACOSX
 #include <Carbon/Carbon.h>
 #include "CocoaFileUtils.h"
+#include "prmem.h"
+#include "plbase64.h"
+
+static nsresult MacErrorMapper(OSErr inErr);
 #endif
 
 #if (MOZ_PLATFORM_MAEMO == 5)
 #include <glib.h>
 #include <hildon-uri.h>
 #include <hildon-mime.h>
 #include <libosso.h>
 #endif
@@ -1715,17 +1719,66 @@ NS_IMETHODIMP
 nsLocalFile::GetPersistentDescriptor(nsACString &aPersistentDescriptor)
 {
     return GetNativePath(aPersistentDescriptor);
 }
 
 NS_IMETHODIMP
 nsLocalFile::SetPersistentDescriptor(const nsACString &aPersistentDescriptor)
 {
+#ifdef XP_MACOSX
+    if (aPersistentDescriptor.IsEmpty())
+        return NS_ERROR_INVALID_ARG;
+
+    // Support pathnames as user-supplied descriptors if they begin with '/'
+    // or '~'.  These characters do not collide with the base64 set used for
+    // encoding alias records.
+    char first = aPersistentDescriptor.First();
+    if (first == '/' || first == '~')
+        return InitWithNativePath(aPersistentDescriptor);
+
+    PRUint32 dataSize = aPersistentDescriptor.Length();    
+    char* decodedData = PL_Base64Decode(PromiseFlatCString(aPersistentDescriptor).get(), dataSize, nsnull);
+    if (!decodedData) {
+        NS_ERROR("SetPersistentDescriptor was given bad data");
+        return NS_ERROR_FAILURE;
+    }
+
+    // Cast to an alias record and resolve.
+    AliasRecord aliasHeader = *(AliasPtr)decodedData;
+    PRInt32 aliasSize = ::GetAliasSizeFromPtr(&aliasHeader);
+    if (aliasSize > ((PRInt32)dataSize * 3) / 4) { // be paranoid about having too few data
+        PR_Free(decodedData);
+        return NS_ERROR_FAILURE;
+    }
+
+    nsresult rv = NS_OK;
+
+    // Move the now-decoded data into the Handle.
+    // The size of the decoded data is 3/4 the size of the encoded data. See plbase64.h
+    Handle  newHandle = nsnull;
+    if (::PtrToHand(decodedData, &newHandle, aliasSize) != noErr)
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    PR_Free(decodedData);
+    if (NS_FAILED(rv))
+        return rv;
+
+    Boolean changed;
+    FSRef resolvedFSRef;
+    OSErr err = ::FSResolveAlias(nsnull, (AliasHandle)newHandle, &resolvedFSRef, &changed);
+
+    rv = MacErrorMapper(err);
+    DisposeHandle(newHandle);
+    if (NS_FAILED(rv))
+        return rv;
+
+    return InitWithFSRef(&resolvedFSRef);  
+#else
     return InitWithNativePath(aPersistentDescriptor);
+#endif
 }
 
 #ifdef XP_BEOS
 NS_IMETHODIMP
 nsLocalFile::Reveal()
 {
     BPath bPath(mPath.get());
     PRBool isDirectory;