Bug 1087646 - Properly serialize nullprincipal URIs across IPC. r=bzbarsky
authorBlake Kaplan <mrbkap@gmail.com>
Tue, 24 Feb 2015 12:54:40 -0800
changeset 230601 fa5a5dbde1c792e759791640bae2936b8555a652
parent 230600 0e60e37671ef86d4b941b49d5f901ded0248e1aa
child 230602 9f4da60dbfff7e506b2649011a755cff0a5ca7a0
push id11492
push usercbook@mozilla.com
push dateWed, 25 Feb 2015 11:14:01 +0000
treeherderfx-team@8edbdb8ca892 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1087646
milestone39.0a1
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!");