Bug 417566 - 'protect against Obj-C exceptions in "toolkit" top-level directory'. r=josh, sr=roc, a=blocking1.9+.
authorbent.mozilla@gmail.com
Wed, 20 Feb 2008 09:34:21 -0800
changeset 11953 84bc5d07700743a7b50814c15cb972eae7aa3daf
parent 11952 b80880a50ea8e61cec585b99e2e8c09ce1eedcec
child 11954 209b3fea85fddfcf6f3ec6295fe42ed2dac120fd
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjosh, roc, blocking1
bugs417566
milestone1.9b4pre
Bug 417566 - 'protect against Obj-C exceptions in "toolkit" top-level directory'. r=josh, sr=roc, a=blocking1.9+.
toolkit/components/alerts/src/mac/mozGrowlDelegate.mm
toolkit/components/alerts/src/mac/nsAlertsImageLoadListener.mm
toolkit/components/alerts/src/mac/nsAlertsService.mm
toolkit/components/alerts/src/mac/nsNotificationsList.mm
toolkit/crashreporter/mac_utils.mm
toolkit/xre/MacApplicationDelegate.mm
toolkit/xre/MacLaunchHelper.m
toolkit/xre/nsNativeAppSupportCocoa.mm
--- a/toolkit/components/alerts/src/mac/mozGrowlDelegate.mm
+++ b/toolkit/components/alerts/src/mac/mozGrowlDelegate.mm
@@ -35,24 +35,27 @@
  * ***** END LICENSE BLOCK ***** */
 
 #import "mozGrowlDelegate.h"
 
 #include "nsIObserver.h"
 #include "nsStringAPI.h"
 #include "nscore.h"
 #include "nsCOMPtr.h"
+#include "nsObjCExceptions.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIXULAppInfo.h"
 #include "nsIStringBundle.h"
 
 @implementation mozGrowlDelegate
 
 - (id) init
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+
   if ((self = [super init])) {
     mKey = 0;
     mDict = [[NSMutableDictionary dictionaryWithCapacity: 8] retain];
     
     mNames   = [[NSMutableArray alloc] init];
     mEnabled = [[NSMutableArray alloc] init];
   
     nsresult rv;
@@ -81,45 +84,61 @@
     }
 
     // Fallback
     [mNames addObject: @"General Notification"];
     [mEnabled addObject: @"General Notification"];
   }
 
   return self;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (void) dealloc
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   [mDict release];
 
   [mNames release];
   [mEnabled release];
 
   [super dealloc];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 - (void) addNotificationNames:(NSArray*)aNames
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   [mNames addObjectsFromArray: aNames];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 - (void) addEnabledNotifications:(NSArray*)aEnabled
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   [mEnabled addObjectsFromArray: aEnabled];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 + (void) notifyWithName:(const nsAString&)aName
                   title:(const nsAString&)aTitle
             description:(const nsAString&)aText
                iconData:(NSData*)aImage
                     key:(PRUint32)aKey
                  cookie:(const nsAString&)aCookie
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   NS_ASSERTION(aName.Length(), "No name specified for the alert!");
   
   NSDictionary* clickContext = nil;
   if (aKey) {
     clickContext = [NSDictionary dictionaryWithObjectsAndKeys:
       [NSNumber numberWithUnsignedInt: aKey],
       OBSERVER_KEY,
       [NSArray arrayWithObject:
@@ -135,55 +154,71 @@
          description: [NSString stringWithCharacters: aText.BeginReading()
                                               length: aText.Length()]
     notificationName: [NSString stringWithCharacters: aName.BeginReading()
                                               length: aName.Length()]
             iconData: aImage
             priority: 0
             isSticky: NO
         clickContext: clickContext];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 - (PRUint32) addObserver:(nsIObserver*)aObserver
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
   NS_ADDREF(aObserver);  // We now own a reference to this!
 
   mKey++;
   [mDict setObject: [NSValue valueWithPointer: aObserver]
             forKey: [NSNumber numberWithUnsignedInt: mKey]];
   return mKey;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
 }
 
 - (NSDictionary *) registrationDictionaryForGrowl
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+
   return [NSDictionary dictionaryWithObjectsAndKeys:
            mNames, GROWL_NOTIFICATIONS_ALL,
            mEnabled, GROWL_NOTIFICATIONS_DEFAULT,
            nil];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (NSString*) applicationNameForGrowl
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+
   nsresult rv;
 
   nsCOMPtr<nsIXULAppInfo> appInfo =
     do_GetService("@mozilla.org/xre/app-info;1", &rv);
   NS_ENSURE_SUCCESS(rv, nil);
 
   nsCAutoString appName;
   rv = appInfo->GetName(appName);
   NS_ENSURE_SUCCESS(rv, nil);
 
   nsAutoString name = NS_ConvertUTF8toUTF16(appName);
   return [NSString stringWithCharacters: name.BeginReading()
                                  length: name.Length()];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (void) growlNotificationTimedOut:(id)clickContext
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   NS_ASSERTION([clickContext valueForKey: OBSERVER_KEY] != nil,
                "OBSERVER_KEY not found!");
   NS_ASSERTION([clickContext valueForKey: COOKIE_KEY] != nil,
                "COOKIE_KEY not found!");
 
   nsIObserver* observer = static_cast<nsIObserver*>
                                      ([[mDict objectForKey: [clickContext valueForKey: OBSERVER_KEY]]
       pointerValue]);
@@ -194,20 +229,24 @@
     nsAutoString tmp;
     tmp.SetLength([cookie length]);
     [cookie getCharacters:tmp.BeginWriting()];
 
     observer->Observe(nsnull, "alertfinished", tmp.get());
 
     NS_RELEASE(observer);
   }
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 - (void) growlNotificationWasClicked:(id)clickContext
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   NS_ASSERTION([clickContext valueForKey: OBSERVER_KEY] != nil,
                "OBSERVER_KEY not found!");
   NS_ASSERTION([clickContext valueForKey: COOKIE_KEY] != nil,
                "COOKIE_KEY not found!");
 
   nsIObserver* observer = static_cast<nsIObserver*>
                                      ([[mDict objectForKey: [clickContext valueForKey: OBSERVER_KEY]]
       pointerValue]);
@@ -219,11 +258,13 @@
     tmp.SetLength([cookie length]);
     [cookie getCharacters:tmp.BeginWriting()];
 
     observer->Observe(nsnull, "alertclickcallback", tmp.get());
     observer->Observe(nsnull, "alertfinished", tmp.get());
 
     NS_RELEASE(observer);
   }
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 @end
--- a/toolkit/components/alerts/src/mac/nsAlertsImageLoadListener.mm
+++ b/toolkit/components/alerts/src/mac/nsAlertsImageLoadListener.mm
@@ -30,16 +30,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsAlertsImageLoadListener.h"
+#include "nsObjCExceptions.h"
 
 #ifdef DEBUG
 #include "nsIRequest.h"
 #include "nsIChannel.h"
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
 #endif
 
@@ -57,16 +58,18 @@ nsAlertsImageLoadListener::nsAlertsImage
 
 NS_IMETHODIMP
 nsAlertsImageLoadListener::OnStreamComplete(nsIStreamLoader* aLoader,
                                             nsISupports* aContext,
                                             nsresult aStatus,
                                             PRUint32 aLength,
                                             const PRUint8* aResult)
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
 #ifdef DEBUG
   // print a load error on bad status
   nsCOMPtr<nsIRequest> request;
   aLoader->GetRequest(getter_AddRefs(request));
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
 
   if (NS_FAILED(aStatus)) {
     if (channel) {
@@ -86,9 +89,11 @@ nsAlertsImageLoadListener::OnStreamCompl
                        description: mAlertText
                           iconData: NS_FAILED(aStatus) ? [NSData data] :
                                       [NSData dataWithBytes: aResult
                                                      length: aLength]
                                key: mAlertListenerKey
                             cookie: mAlertCookie];
 
   return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
--- a/toolkit/components/alerts/src/mac/nsAlertsService.mm
+++ b/toolkit/components/alerts/src/mac/nsAlertsService.mm
@@ -40,49 +40,60 @@
 #include "nsIURI.h"
 #include "nsIStreamLoader.h"
 #include "nsNetUtil.h"
 #include "nsCOMPtr.h"
 #include "nsIStringBundle.h"
 #include "nsIObserverService.h"
 #include "nsAutoPtr.h"
 #include "nsNotificationsList.h"
+#include "nsObjCExceptions.h"
 
 #import "mozGrowlDelegate.h"
 #import "GrowlApplicationBridge.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 //// GrowlDelegateWrapper
 
 struct GrowlDelegateWrapper
 {
   mozGrowlDelegate* delegate;
 
   GrowlDelegateWrapper()
   {
+    NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
     delegate = [[mozGrowlDelegate alloc] init];
+
+    NS_OBJC_END_TRY_ABORT_BLOCK;
   }
 
   ~GrowlDelegateWrapper()
   {
+    NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
     [delegate release];
+
+    NS_OBJC_END_TRY_ABORT_BLOCK;
   }
 };
 
 /**
  * Helper function to dispatch a notification to Growl
  */
 static nsresult
 DispatchNamedNotification(const nsAString &aName,
                           const nsAString &aImage,
                           const nsAString &aTitle,
                           const nsAString &aMessage,
                           const nsAString &aCookie,
                           nsIObserver *aListener)
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
   if ([GrowlApplicationBridge isGrowlInstalled] == NO ||
       [GrowlApplicationBridge isGrowlRunning] == NO)
     return NS_ERROR_NOT_AVAILABLE;
   
   mozGrowlDelegate *delegate =
     static_cast<mozGrowlDelegate *>([GrowlApplicationBridge growlDelegate]);
   if (!delegate)
     return NS_ERROR_NOT_AVAILABLE;
@@ -106,16 +117,18 @@ DispatchNamedNotification(const nsAStrin
 
   nsCOMPtr<nsAlertsImageLoadListener> listener =
     new nsAlertsImageLoadListener(aName, aTitle, aMessage, aCookie, ind);
   if (!listener)
     return NS_ERROR_OUT_OF_MEMORY;
 
   nsCOMPtr<nsIStreamLoader> loader;
   return NS_NewStreamLoader(getter_AddRefs(loader), uri, listener);
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsAlertsService
 
 NS_IMPL_THREADSAFE_ADDREF(nsAlertsService)
 NS_IMPL_THREADSAFE_RELEASE(nsAlertsService)
 
@@ -123,25 +136,29 @@ NS_INTERFACE_MAP_BEGIN(nsAlertsService)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAlertsService)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsIAlertsService)
 NS_INTERFACE_MAP_END_THREADSAFE
 
 nsresult
 nsAlertsService::Init()
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
   if ([GrowlApplicationBridge isGrowlInstalled] == NO)
     return NS_ERROR_SERVICE_NOT_AVAILABLE;
 
   nsresult rv;
   nsCOMPtr<nsIObserverService> os =
     do_GetService("@mozilla.org/observer-service;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return os->AddObserver(this, "final-ui-startup", PR_FALSE);
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 nsAlertsService::nsAlertsService() : mDelegate(nsnull) {}
 
 nsAlertsService::~nsAlertsService()
 {
   if (mDelegate)
     delete mDelegate;
@@ -154,16 +171,18 @@ NS_IMETHODIMP
 nsAlertsService::ShowAlertNotification(const nsAString& aImageUrl,
                                        const nsAString& aAlertTitle,
                                        const nsAString& aAlertText,
                                        PRBool aAlertClickable,
                                        const nsAString& aAlertCookie,
                                        nsIObserver* aAlertListener,
                                        const nsAString& aAlertName)
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
   NS_ASSERTION(mDelegate->delegate == [GrowlApplicationBridge growlDelegate],
                "Growl Delegate was not registered properly.");
 
   if (!aAlertName.IsEmpty()) {
     return DispatchNamedNotification(aAlertTitle, aImageUrl, aAlertTitle,
                                      aAlertText, aAlertCookie, aAlertListener);
   }
 
@@ -182,25 +201,29 @@ nsAlertsService::ShowAlertNotification(c
                                      getter_Copies(name));
       if (NS_FAILED(rv))
         name = NS_LITERAL_STRING("General Notification");
     }
   }
 
   return DispatchNamedNotification(name, aImageUrl, aAlertTitle,
                                    aAlertText, aAlertCookie, aAlertListener);
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsIObserver
 
 NS_IMETHODIMP
 nsAlertsService::Observe(nsISupports* aSubject, const char* aTopic,
                          const PRUnichar* aData)
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
   if (strcmp(aTopic, "final-ui-startup") == 0) {
     NS_ASSERTION([GrowlApplicationBridge growlDelegate] == nil,
                  "We already registered with Growl!");
 
     nsRefPtr<nsNotificationsList> notifications = new nsNotificationsList();
 
     if (notifications) {
       nsCOMPtr<nsIObserverService> os =
@@ -213,10 +236,11 @@ nsAlertsService::Observe(nsISupports* aS
     if (notifications)
       notifications->informController(mDelegate->delegate);
 
     // registers with Growl
     [GrowlApplicationBridge setGrowlDelegate: mDelegate->delegate];
   }
 
   return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
-
--- a/toolkit/components/alerts/src/mac/nsNotificationsList.mm
+++ b/toolkit/components/alerts/src/mac/nsNotificationsList.mm
@@ -31,61 +31,82 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsNotificationsList.h"
+#include "nsObjCExceptions.h"
 #include "nsStringAPI.h"
 
 NS_IMPL_ADDREF(nsNotificationsList)
 NS_IMPL_RELEASE(nsNotificationsList)
 
 NS_INTERFACE_MAP_BEGIN(nsNotificationsList)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsINotificationsList)
   NS_INTERFACE_MAP_ENTRY(nsINotificationsList)
 NS_INTERFACE_MAP_END
 
 nsNotificationsList::nsNotificationsList()
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   mNames   = [[NSMutableArray alloc] init];
   mEnabled = [[NSMutableArray alloc] init];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 nsNotificationsList::~nsNotificationsList()
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   [mNames release];
   [mEnabled release];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 NS_IMETHODIMP
 nsNotificationsList::AddNotification(const nsAString &aName, PRBool aEnabled)
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
   NSString *name = [NSString stringWithCharacters: aName.BeginReading()
                                            length: aName.Length()];
 
   [mNames addObject: name];
 
   if (aEnabled)
     [mEnabled addObject: name];
 
   return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 NS_IMETHODIMP
 nsNotificationsList::IsNotification(const nsAString &aName, PRBool *retVal)
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
   NSString *name = [NSString stringWithCharacters: aName.BeginReading()
                                            length: aName.Length()];
 
   *retVal = [mNames containsObject: name] ? PR_TRUE : PR_FALSE;
   return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 void
 nsNotificationsList::informController(mozGrowlDelegate *aController)
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   [aController addNotificationNames: mNames];
   [aController addEnabledNotifications: mEnabled];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
--- a/toolkit/crashreporter/mac_utils.mm
+++ b/toolkit/crashreporter/mac_utils.mm
@@ -33,18 +33,23 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include <Foundation/Foundation.h>
 
 #include "mac_utils.h"
+#include "nsObjCExceptions.h"
 
 bool PassToOSCrashReporter()
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
   NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
   BOOL osCrashReporter = [userDefaults boolForKey:@"OSCrashReporter"];
   [pool release];
 
   return osCrashReporter == YES;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);
 }
--- a/toolkit/xre/MacApplicationDelegate.mm
+++ b/toolkit/xre/MacApplicationDelegate.mm
@@ -52,45 +52,54 @@
 #include "nsIWindowMediator.h"
 #include "nsAppRunner.h"
 #include "nsComponentManagerUtils.h"
 #include "nsCommandLineServiceMac.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIAppStartup.h"
 #include "nsIObserverService.h"
 #include "nsISupportsPrimitives.h"
+#include "nsObjCExceptions.h"
 
 @interface MacApplicationDelegate : NSObject
 {
 }
 
 @end
 
 // Something to call from non-objective code.
 
 // This is needed, on relaunch, to force the OS to use the "Cocoa Dock API"
 // instead of the "Carbon Dock API".  For more info see bmo bug 377166.
 void
 EnsureUseCocoaDockAPI()
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   [NSApplication sharedApplication];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 void
 SetupMacApplicationDelegate()
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   // This call makes it so that application:openFile: doesn't get bogus calls
   // from Cocoa doing its own parsing of the argument string. And yes, we need
   // to use a string with a boolean value in it. That's just how it works.
   [[NSUserDefaults standardUserDefaults] setObject:@"NO"
                                             forKey:@"NSTreatUnknownArgumentsAsOpen"];
 
   // Create the delegate. This should be around for the lifetime of the app.
   MacApplicationDelegate *delegate = [[MacApplicationDelegate alloc] init];
   [[NSApplication sharedApplication] setDelegate:delegate];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 @implementation MacApplicationDelegate
 
 // Opening the application is handled specially elsewhere,
 // don't define applicationOpenUntitledFile: .
 
 // The method that NSApplication calls upon a request to reopen, such as when
@@ -111,16 +120,18 @@ SetupMacApplicationDelegate()
   return NO;
 }
 
 // The method that NSApplication calls when documents are requested to be opened.
 // It will be called once for each selected document.
 
 - (BOOL)application:(NSApplication*)theApplication openFile:(NSString*)filename
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
   FSRef ref;
   FSSpec spec;
   // The cast is kind of freaky, but apparently it's what all the beautiful people do.
   OSStatus status = FSPathMakeRef((UInt8 *)[filename fileSystemRepresentation], &ref, NULL);
   if (status != noErr) {
     NS_WARNING("FSPathMakeRef in openFile failed, skipping file open");
     return NO;
   }
@@ -131,24 +142,28 @@ SetupMacApplicationDelegate()
   }
 
   // Take advantage of the existing "command line" code for Macs.
   nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
   // We don't actually care about Mac filetypes in this context, just pass a placeholder.
   cmdLine.HandleOpenOneDoc(spec, 'abcd');
 
   return YES;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
 }
 
 // The method that NSApplication calls when documents are requested to be printed
 // from the Finder (under the "File" menu).
 // It will be called once for each selected document.
 
 - (BOOL)application:(NSApplication*)theApplication printFile:(NSString*)filename
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
   FSRef ref;
   FSSpec spec;
   // The cast is kind of freaky, but apparently it's what all the beautiful people do.
   OSStatus status = FSPathMakeRef((UInt8 *)[filename fileSystemRepresentation], &ref, NULL);
   if (status != noErr) {
     NS_WARNING("FSPathMakeRef in printFile failed, skipping printing");
     return NO;
   }
@@ -159,16 +174,18 @@ SetupMacApplicationDelegate()
   }
 
   // Take advantage of the existing "command line" code for Macs.
   nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
   // We don't actually care about Mac filetypes in this context, just pass a placeholder.
   cmdLine.HandlePrintOneDoc(spec, 'abcd');
 
   return YES;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
 }
 
 // Drill down from nsIXULWindow and get an NSWindow. We get passed nsISupports
 // because that's what nsISimpleEnumerator returns.
 
 static NSWindow* GetCocoaWindowForXULWindow(nsISupports *aXULWindow)
 {
   nsresult rv;
@@ -180,16 +197,18 @@ static NSWindow* GetCocoaWindowForXULWin
   // If it fails, we return nil anyway, no biggie
   return (NSWindow *)widget->GetNativeData(NS_NATIVE_WINDOW);
 }
 
 // Create the menu that shows up in the Dock.
 
 - (NSMenu*)applicationDockMenu:(NSApplication*)sender
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+
   // Why we're not just using Cocoa to enumerate our windows:
   // The Dock thinks we're a Carbon app, probably because we don't have a
   // blessed Window menu, so we get none of the automatic handling for dock
   // menus that Cocoa apps get. Add in Cocoa being a bit braindead when you hide
   // the app, and we end up having to get our list of windows via XPCOM. Ugh.
 
   // Get the window mediator to do all our lookups.
   nsresult rv;
@@ -237,24 +256,30 @@ static NSWindow* GetCocoaWindowForXULWin
     // If this is the foreground window, put a checkmark next to it
     if (SameCOMIdentity(xulWindow, frontWindow))
       [menuItem setState:NSOnState];
 
     [menu addItem:menuItem];
     [menuItem release];
   }
   return menu;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 // One of our dock menu items was selected
 - (void)dockMenuItemSelected:(id)sender
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   // Our represented object is an NSWindow
   [[sender representedObject] makeKeyAndOrderFront:nil];
   [NSApp activateIgnoringOtherApps:YES];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 // The open contents Apple Event 'ocon' (new in 10.4) does not have a delegate method
 // associated with it; it would need Carbon event code to handle.
 
 // If we don't handle applicationShouldTerminate:, a call to [NSApp terminate:]
 // (from the browser or from the OS) can result in an unclean shutdown.
 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
--- a/toolkit/xre/MacLaunchHelper.m
+++ b/toolkit/xre/MacLaunchHelper.m
@@ -33,26 +33,30 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "MacLaunchHelper.h"
 
+#include "nsObjCExceptions.h"
+
 #include <Cocoa/Cocoa.h>
 
 #ifdef __ppc__
 #include <sys/types.h>
 #include <sys/sysctl.h>
 #include <mach/machine.h>
 #endif /* __ppc__ */
 
 void LaunchChildMac(int aArgc, char** aArgv)
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
   int i;
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
   NSTask* child = [[[NSTask alloc] init] autorelease];
   NSMutableArray* args = [[[NSMutableArray alloc] init] autorelease];
 
 #ifdef __ppc__
   // It's possible that the app is a universal binary running under Rosetta
   // translation because the user forced it to.  Relaunching via NSTask would
@@ -81,10 +85,12 @@ void LaunchChildMac(int aArgc, char** aA
   for (i = 1; i < aArgc; ++i) 
     [args addObject: [NSString stringWithCString: aArgv[i]]];
   
   [child setCurrentDirectoryPath:[[[NSBundle mainBundle] executablePath] stringByDeletingLastPathComponent]];
   [child setLaunchPath:[[NSBundle mainBundle] executablePath]];
   [child setArguments:args];
   [child launch];
   [pool release];
+
+  NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
--- a/toolkit/xre/nsNativeAppSupportCocoa.mm
+++ b/toolkit/xre/nsNativeAppSupportCocoa.mm
@@ -37,16 +37,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsString.h"
 
 #import <Carbon/Carbon.h>
 #import <Cocoa/Cocoa.h>
 
 #include "nsCOMPtr.h"
+#include "nsObjCExceptions.h"
 #include "nsNativeAppSupportBase.h"
 
 #include "nsIAppShellService.h"
 #include "nsIAppStartup.h"
 #include "nsIBaseWindow.h"
 #include "nsICommandLineRunner.h"
 #include "nsIDOMWindowInternal.h"
 #include "nsIDocShellTreeItem.h"
@@ -99,16 +100,18 @@ nsNativeAppSupportCocoa::Enable()
 {
   mCanShowUI = PR_TRUE;
   return NS_OK;
 }
 
 /* boolean start (); */
 NS_IMETHODIMP nsNativeAppSupportCocoa::Start(PRBool *_retval)
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
   long response = 0;
   OSErr err = ::Gestalt (gestaltSystemVersion, &response);
   response &= 0xFFFF; // The system version is in the low order word
 
   // Check for at least Mac OS X 10.4, and if that fails return PR_FALSE,
   // which will make the browser quit.  In principle we could display an
   // alert here.  But the alert's message and buttons would require custom
   // localization.  So (for now at least) we just log an English message
@@ -116,21 +119,25 @@ NS_IMETHODIMP nsNativeAppSupportCocoa::S
   if ((err != noErr) || response < 0x00001040)
   {
     NSLog(@"Requires Mac OS X version 10.4 or newer");
     return PR_FALSE;
   }
 
   *_retval = PR_TRUE;
   return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 NS_IMETHODIMP
 nsNativeAppSupportCocoa::ReOpen()
 {
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
   if (!mCanShowUI)
     return NS_ERROR_FAILURE;
 
   PRBool haveNonMiniaturized = PR_FALSE;
   PRBool haveOpenWindows = PR_FALSE;
   PRBool done = PR_FALSE;
   
   nsCOMPtr<nsIWindowMediator> 
@@ -207,16 +214,18 @@ nsNativeAppSupportCocoa::ReOpen()
                          nsICommandLine::STATE_REMOTE_EXPLICIT);
       NS_ENSURE_SUCCESS(rv, rv);
 
       return cmdLine->Run();
     }
     
   } // got window mediator
   return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 nsresult
 GetNativeWindowPointerFromDOMWindow(nsIDOMWindowInternal *a_window, NSWindow **a_nativeWindow)
 {
     *a_nativeWindow = nil;
     if (!a_window) return NS_ERROR_INVALID_ARG;