Bug 1448772 - Avoid back-and-forth UTF-16 to UTF-8 to UTF-16 conversions in xpcom/base/MacHelpers.mm. draft
authorHenri Sivonen <hsivonen@hsivonen.fi>
Mon, 26 Mar 2018 10:49:02 +0300
changeset 776022 d537568096cdd97dcc851a96fd25686279d5e778
parent 772438 bc8e1ff08c2df21ae8b61ae2afe7e7d4dfca4469
push id104784
push userbmo:hsivonen@hsivonen.fi
push dateMon, 02 Apr 2018 12:59:25 +0000
bugs1448772
milestone61.0a1
Bug 1448772 - Avoid back-and-forth UTF-16 to UTF-8 to UTF-16 conversions in xpcom/base/MacHelpers.mm. MozReview-Commit-ID: LQ4ZMJzy5WI
toolkit/crashreporter/mac_utils.mm
xpcom/base/MacHelpers.mm
xpcom/base/MacStringHelpers.h
xpcom/base/MacStringHelpers.mm
xpcom/base/moz.build
--- a/toolkit/crashreporter/mac_utils.mm
+++ b/toolkit/crashreporter/mac_utils.mm
@@ -2,40 +2,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <Foundation/Foundation.h>
 
 #include "mac_utils.h"
 #include "nsXPCOM.h"
+#include "mozilla/MacStringHelpers.h"
+#include "mozilla/Unused.h"
 
 void GetObjCExceptionInfo(void* inException, nsACString& outString)
 {
   NSException* e = (NSException*)inException;
 
   NSString* name = [e name];
   NSString* reason = [e reason];
-  unsigned int nameLength = [name length];
-  unsigned int reasonLength = [reason length];
 
-  unichar* nameBuffer = (unichar*)moz_xmalloc(sizeof(unichar) * (nameLength + 1));
-  if (!nameBuffer)
-    return;
-  unichar* reasonBuffer = (unichar*)moz_xmalloc(sizeof(unichar) * (reasonLength + 1));
-  if (!reasonBuffer) {
-    free(nameBuffer);
-    return;
-  }
+  nsAutoString nameStr;
+  nsAutoString reasonStr;
 
-  [name getCharacters:nameBuffer];
-  [reason getCharacters:reasonBuffer];
-  nameBuffer[nameLength] = '\0';
-  reasonBuffer[reasonLength] = '\0';
+  mozilla::Unused << mozilla::CopyCocoaStringToXPCOMString(name, nameStr);
+  mozilla::Unused << mozilla::CopyCocoaStringToXPCOMString(reason, reasonStr);
 
   outString.AssignLiteral("\nObj-C Exception data:\n");
-  AppendUTF16toUTF8(reinterpret_cast<const char16_t*>(nameBuffer), outString);
+  AppendUTF16toUTF8(nameStr, outString);
   outString.AppendLiteral(": ");
-  AppendUTF16toUTF8(reinterpret_cast<const char16_t*>(reasonBuffer), outString);
-
-  free(nameBuffer);
-  free(reasonBuffer);
+  AppendUTF16toUTF8(reasonStr, outString);
 }
--- a/xpcom/base/MacHelpers.mm
+++ b/xpcom/base/MacHelpers.mm
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsString.h"
 #include "MacHelpers.h"
+#include "MacStringHelpers.h"
 #include "nsObjCExceptions.h"
 
 #import <Foundation/Foundation.h>
 
 namespace mozilla {
 
 nsresult
 GetSelectedCityInfo(nsAString& aCountryCode)
@@ -20,22 +21,15 @@ GetSelectedCityInfo(nsAString& aCountryC
   // Can be replaced with [[NSLocale currentLocale] countryCode] once we build
   // with the 10.12 SDK.
   id countryCode = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
 
   if (![countryCode isKindOfClass:[NSString class]]) {
     return NS_ERROR_FAILURE;
   }
 
-  const char* countryCodeUTF8 = [(NSString*)countryCode UTF8String];
-
-  if (!countryCodeUTF8) {
-    return NS_ERROR_FAILURE;
-  }
-
-  AppendUTF8toUTF16(countryCodeUTF8, aCountryCode);
-  return NS_OK;
+  return mozilla::CopyCocoaStringToXPCOMString((NSString*)countryCode, aCountryCode);
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 } // namespace Mozilla
 
new file mode 100644
--- /dev/null
+++ b/xpcom/base/MacStringHelpers.h
@@ -0,0 +1,20 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_MacStringHelpers_h
+#define mozilla_MacStringHelpers_h
+
+#include "nsString.h"
+
+#import <Foundation/Foundation.h>
+
+namespace mozilla {
+
+nsresult CopyCocoaStringToXPCOMString(NSString* aFrom, nsAString& aTo);
+
+} // namespace Mozilla
+
+#endif
new file mode 100644
--- /dev/null
+++ b/xpcom/base/MacStringHelpers.mm
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "MacStringHelpers.h"
+#include "nsObjCExceptions.h"
+
+#include "mozilla/IntegerTypeTraits.h"
+
+namespace mozilla {
+
+nsresult
+CopyCocoaStringToXPCOMString(NSString* aFrom, nsAString& aTo)
+{
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+  NSUInteger len = [aFrom length];
+  if (len > MaxValue<nsAString::size_type>::value) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  if (!aTo.SetLength(len, mozilla::fallible)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  [aFrom getCharacters:reinterpret_cast<unichar*>(aTo.BeginWriting()) range:NSMakeRange(0, len)];
+
+  return NS_OK;
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+} // namespace Mozilla
--- a/xpcom/base/moz.build
+++ b/xpcom/base/moz.build
@@ -29,19 +29,21 @@ XPIDL_SOURCES += [
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     XPIDL_SOURCES += [
         'nsIMacUtils.idl',
     ]
     EXPORTS.mozilla += [
         'MacHelpers.h',
+        'MacStringHelpers.h',
     ]
     UNIFIED_SOURCES += [
         'MacHelpers.mm',
+        'MacStringHelpers.mm',
     ]
 
 XPIDL_MODULE = 'xpcom_base'
 
 EXPORTS += [
     '!ErrorList.h',
     '!ErrorNamesInternal.h',
     'CodeAddressService.h',