Bug 1087646 - Properly serialize nullprincipal URIs across IPC. r=bzbarsky
authorBlake Kaplan <mrbkap@gmail.com>
Tue, 24 Feb 2015 12:54:40 -0800
changeset 260889 fa5a5dbde1c792e759791640bae2936b8555a652
parent 260888 0e60e37671ef86d4b941b49d5f901ded0248e1aa
child 260890 9f4da60dbfff7e506b2649011a755cff0a5ca7a0
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1087646
milestone39.0a1
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 1087646 - Properly serialize nullprincipal URIs across IPC. r=bzbarsky
caps/moz.build
caps/nsNullPrincipal.cpp
caps/nsNullPrincipal.h
caps/nsNullPrincipalURI.cpp
caps/nsNullPrincipalURI.h
ipc/glue/URIParams.ipdlh
ipc/glue/URIUtils.cpp
--- a/caps/moz.build
+++ b/caps/moz.build
@@ -12,16 +12,17 @@ XPIDL_SOURCES += [
     'nsIScriptSecurityManager.idl',
 ]
 
 XPIDL_MODULE = 'caps'
 
 EXPORTS += [
     'nsJSPrincipals.h',
     'nsNullPrincipal.h',
+    'nsNullPrincipalURI.h',
 ]
 
 UNIFIED_SOURCES += [
     'DomainPolicy.cpp',
     'nsJSPrincipals.cpp',
     'nsNullPrincipal.cpp',
     'nsNullPrincipalURI.cpp',
     'nsPrincipal.cpp',
@@ -31,11 +32,13 @@ UNIFIED_SOURCES += [
 
 MSVC_ENABLE_PGO = True
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/js/xpconnect/src',
 ]
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
 FINAL_LIBRARY = 'xul'
 
 FAIL_ON_WARNINGS = True
--- a/caps/nsNullPrincipal.cpp
+++ b/caps/nsNullPrincipal.cpp
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 sts=2 ts=2 et 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/. */
 
 /**
  * This is the principal that has no rights and can't be accessed by
  * anything other than itself and chrome; null principals are not
  * same-origin with anything but themselves.
@@ -81,16 +82,34 @@ nsNullPrincipal::CreateWithInheritedAttr
 
 nsresult
 nsNullPrincipal::Init(uint32_t aAppId, bool aInMozBrowser)
 {
   MOZ_ASSERT(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
   mAppId = aAppId;
   mInMozBrowser = aInMozBrowser;
 
+  nsCString str;
+  nsresult rv = GenerateNullPrincipalURI(str);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  mURI = new nsNullPrincipalURI(str);
+
+  return NS_OK;
+}
+
+void
+nsNullPrincipal::GetScriptLocation(nsACString &aStr)
+{
+  mURI->GetSpec(aStr);
+}
+
+nsresult
+nsNullPrincipal::GenerateNullPrincipalURI(nsACString &aStr)
+{
   // FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant.
   nsresult rv;
   nsCOMPtr<nsIUUIDGenerator> uuidgen =
     do_GetService("@mozilla.org/uuid-generator;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsID id;
   rv = uuidgen->GenerateUUIDInPlace(&id);
@@ -99,38 +118,29 @@ nsNullPrincipal::Init(uint32_t aAppId, b
   char chars[NSID_LENGTH];
   id.ToProvidedString(chars);
 
   uint32_t suffixLen = NSID_LENGTH - 1;
   uint32_t prefixLen = ArrayLength(NS_NULLPRINCIPAL_PREFIX) - 1;
 
   // Use an nsCString so we only do the allocation once here and then share
   // with nsJSPrincipals
-  nsCString str;
-  str.SetCapacity(prefixLen + suffixLen);
+  aStr.SetCapacity(prefixLen + suffixLen);
 
-  str.Append(NS_NULLPRINCIPAL_PREFIX);
-  str.Append(chars);
+  aStr.Append(NS_NULLPRINCIPAL_PREFIX);
+  aStr.Append(chars);
 
-  if (str.Length() != prefixLen + suffixLen) {
+  if (aStr.Length() != prefixLen + suffixLen) {
     NS_WARNING("Out of memory allocating null-principal URI");
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  mURI = new nsNullPrincipalURI(str);
-
   return NS_OK;
 }
 
-void
-nsNullPrincipal::GetScriptLocation(nsACString &aStr)
-{
-  mURI->GetSpec(aStr);
-}
-
 #ifdef DEBUG
 void nsNullPrincipal::dumpImpl()
 {
   nsAutoCString str;
   mURI->GetSpec(str);
   fprintf(stderr, "nsNullPrincipal (%p) = %s\n", this, str.get());
 }
 #endif 
--- a/caps/nsNullPrincipal.h
+++ b/caps/nsNullPrincipal.h
@@ -26,17 +26,17 @@ class nsIURI;
 #define NS_NULLPRINCIPAL_CONTRACTID "@mozilla.org/nullprincipal;1"
 
 #define NS_NULLPRINCIPAL_SCHEME "moz-nullprincipal"
 
 class nsNullPrincipal MOZ_FINAL : public nsJSPrincipals
 {
 public:
   nsNullPrincipal();
-  
+
   // Our refcount is managed by nsJSPrincipals.  Use this macro to avoid an
   // extra refcount member.
 
   // FIXME: bug 327245 -- I sorta wish there were a clean way to share the
   // nsJSPrincipals munging code between the various principal classes without
   // giving up the NS_DECL_NSIPRINCIPAL goodness.
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIPRINCIPAL
@@ -44,16 +44,18 @@ public:
 
   static already_AddRefed<nsNullPrincipal> CreateWithInheritedAttributes(nsIPrincipal *aInheritFrom);
 
   nsresult Init(uint32_t aAppId = nsIScriptSecurityManager::NO_APP_ID,
                 bool aInMozBrowser = false);
 
   virtual void GetScriptLocation(nsACString &aStr) MOZ_OVERRIDE;
 
+  static nsresult GenerateNullPrincipalURI(nsACString &aStr);
+
 #ifdef DEBUG
   virtual void dumpImpl() MOZ_OVERRIDE;
 #endif 
 
  protected:
   virtual ~nsNullPrincipal();
 
   nsCOMPtr<nsIURI> mURI;
--- a/caps/nsNullPrincipalURI.cpp
+++ b/caps/nsNullPrincipalURI.cpp
@@ -4,25 +4,33 @@
  * 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 "nsNullPrincipalURI.h"
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/MemoryReporting.h"
 
+#include "mozilla/ipc/URIParams.h"
+
 #include "nsNetUtil.h"
 #include "nsEscape.h"
 #include "nsCRT.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsNullPrincipalURI
 
 nsNullPrincipalURI::nsNullPrincipalURI(const nsCString &aSpec)
 {
+  InitializeFromSpec(aSpec);
+}
+
+void
+nsNullPrincipalURI::InitializeFromSpec(const nsCString &aSpec)
+{
   int32_t dividerPosition = aSpec.FindChar(':');
   NS_ASSERTION(dividerPosition != -1, "Malformed URI!");
 
   mozilla::DebugOnly<int32_t> n = aSpec.Left(mScheme, dividerPosition);
   NS_ASSERTION(n == dividerPosition, "Storing the scheme failed!");
 
   int32_t count = aSpec.Length() - dividerPosition - 1;
   n = aSpec.Mid(mPath, dividerPosition + 1, count);
@@ -39,16 +47,17 @@ NS_IMPL_RELEASE(nsNullPrincipalURI)
 
 NS_INTERFACE_MAP_BEGIN(nsNullPrincipalURI)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURI)
   if (aIID.Equals(kNullPrincipalURIImplementationCID))
     foundInterface = static_cast<nsIURI *>(this);
   else
   NS_INTERFACE_MAP_ENTRY(nsIURI)
   NS_INTERFACE_MAP_ENTRY(nsISizeOf)
+  NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableURI)
 NS_INTERFACE_MAP_END
 
 ////////////////////////////////////////////////////////////////////////////////
 //// nsIURI
 
 NS_IMETHODIMP
 nsNullPrincipalURI::GetAsciiHost(nsACString &_host)
 {
@@ -268,16 +277,41 @@ nsNullPrincipalURI::Resolve(const nsACSt
 NS_IMETHODIMP
 nsNullPrincipalURI::SchemeIs(const char *aScheme, bool *_schemeIs)
 {
   *_schemeIs = (0 == nsCRT::strcasecmp(mScheme.get(), aScheme));
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+//// nsIIPCSerializableURI
+
+void
+nsNullPrincipalURI::Serialize(mozilla::ipc::URIParams &aParams)
+{
+  aParams = mozilla::ipc::NullPrincipalURIParams();
+}
+
+bool
+nsNullPrincipalURI::Deserialize(const mozilla::ipc::URIParams &aParams)
+{
+  if (aParams.type() != mozilla::ipc::URIParams::TNullPrincipalURIParams) {
+    MOZ_ASSERT_UNREACHABLE("unexpected URIParams type");
+    return false;
+  }
+
+  nsCString str;
+  nsresult rv = nsNullPrincipal::GenerateNullPrincipalURI(str);
+  NS_ENSURE_SUCCESS(rv, false);
+
+  InitializeFromSpec(str);
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
 //// nsISizeOf
 
 size_t
 nsNullPrincipalURI::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   return mScheme.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
          mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
 }
--- a/caps/nsNullPrincipalURI.h
+++ b/caps/nsNullPrincipalURI.h
@@ -11,36 +11,44 @@
 #ifndef __nsNullPrincipalURI_h__
 #define __nsNullPrincipalURI_h__
 
 #include "nsIURI.h"
 #include "nsISizeOf.h"
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "mozilla/Attributes.h"
+#include "nsIIPCSerializableURI.h"
 #include "mozilla/MemoryReporting.h"
 
 // {51fcd543-3b52-41f7-b91b-6b54102236e6}
 #define NS_NULLPRINCIPALURI_IMPLEMENTATION_CID \
   {0x51fcd543, 0x3b52, 0x41f7, \
     {0xb9, 0x1b, 0x6b, 0x54, 0x10, 0x22, 0x36, 0xe6} }
 
 class nsNullPrincipalURI MOZ_FINAL : public nsIURI
                                    , public nsISizeOf
+                                   , public nsIIPCSerializableURI
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIURI
+  NS_DECL_NSIIPCSERIALIZABLEURI
 
   // nsISizeOf
   virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
 
   explicit nsNullPrincipalURI(const nsCString &aSpec);
 
+  // NB: This constructor exists only for deserialization.
+  nsNullPrincipalURI() { }
+
 private:
   ~nsNullPrincipalURI() {}
 
+  void InitializeFromSpec(const nsCString &aSpec);
+
   nsCString mScheme;
   nsCString mPath;
 };
 
 #endif // __nsNullPrincipalURI_h__
--- a/ipc/glue/URIParams.ipdlh
+++ b/ipc/glue/URIParams.ipdlh
@@ -59,22 +59,28 @@ struct IconURIParams
   uint32_t size;
   nsCString contentType;
   nsCString fileName;
   nsCString stockIcon;
   int32_t iconSize;
   int32_t iconState;
 };
 
+struct NullPrincipalURIParams
+{
+  // Purposefully empty. Null principal URIs do not round-trip.
+};
+
 union URIParams
 {
   SimpleURIParams;
   StandardURLParams;
   JARURIParams;
   IconURIParams;
+  NullPrincipalURIParams;
 };
 
 union OptionalURIParams
 {
   void_t;
   URIParams;
 };
 
--- a/ipc/glue/URIUtils.cpp
+++ b/ipc/glue/URIUtils.cpp
@@ -8,16 +8,17 @@
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
 #include "nsComponentManagerUtils.h"
 #include "nsDebug.h"
 #include "nsID.h"
 #include "nsJARURI.h"
 #include "nsIIconURI.h"
+#include "nsNullPrincipalURI.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsThreadUtils.h"
 
 using namespace mozilla::ipc;
 using mozilla::ArrayLength;
 
 namespace {
@@ -36,17 +37,17 @@ void
 SerializeURI(nsIURI* aURI,
              URIParams& aParams)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aURI);
 
   nsCOMPtr<nsIIPCSerializableURI> serializable = do_QueryInterface(aURI);
   if (!serializable) {
-    MOZ_CRASH("All IPDL URIs must be serializable scheme!");
+    MOZ_CRASH("All IPDL URIs must be serializable!");
   }
 
   serializable->Serialize(aParams);
   if (aParams.type() == URIParams::T__None) {
     MOZ_CRASH("Serialize failed!");
   }
 }
 
@@ -85,16 +86,20 @@ DeserializeURI(const URIParams& aParams)
     case URIParams::TJARURIParams:
       serializable = do_CreateInstance(kJARURICID);
       break;
 
     case URIParams::TIconURIParams:
       serializable = do_CreateInstance(kIconURICID);
       break;
 
+    case URIParams::TNullPrincipalURIParams:
+      serializable = new nsNullPrincipalURI();
+      break;
+
     default:
       MOZ_CRASH("Unknown params!");
   }
 
   MOZ_ASSERT(serializable);
 
   if (!serializable->Deserialize(aParams)) {
     MOZ_ASSERT(false, "Deserialize failed!");