Bug 652991 - Part 1. Bring local-reference flag into nsIURI; draft
authorCJKu <cku@mozilla.com>
Tue, 03 May 2016 18:14:10 +0800
changeset 362844 546b7103f08dce90652681c0800960deda3c46e8
parent 358327 77cead2cd20300623eea2416bc9bce4d5021df09
child 362845 fe3dfab6dfd4a97531d1d5e9c7c81213ccc5c00e
push id17044
push usercku@mozilla.com
push dateTue, 03 May 2016 10:15:34 +0000
bugs652991
milestone49.0a1
Bug 652991 - Part 1. Bring local-reference flag into nsIURI; MozReview-Commit-ID: IAuK7sx0HQc
caps/nsNullPrincipalURI.cpp
image/decoders/icon/nsIconURI.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
layout/style/nsStyleStruct.h
modules/libjar/nsJARURI.cpp
netwerk/base/nsIURI.idl
netwerk/base/nsSimpleURI.cpp
netwerk/base/nsSimpleURI.h
netwerk/base/nsStandardURL.cpp
netwerk/base/nsStandardURL.h
--- a/caps/nsNullPrincipalURI.cpp
+++ b/caps/nsNullPrincipalURI.cpp
@@ -301,16 +301,30 @@ nsNullPrincipalURI::Resolve(const nsACSt
 
 NS_IMETHODIMP
 nsNullPrincipalURI::SchemeIs(const char *aScheme, bool *_schemeIs)
 {
   *_schemeIs = (0 == nsCRT::strcasecmp(NS_NULLPRINCIPAL_SCHEME, aScheme));
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsNullPrincipalURI::GetIsLocalRef(bool*)
+{
+    MOZ_ASSERT(false);
+    return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsNullPrincipalURI::SetIsLocalRef(bool)
+{
+    MOZ_ASSERT(false);
+    return NS_ERROR_FAILURE;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //// nsIIPCSerializableURI
 
 void
 nsNullPrincipalURI::Serialize(mozilla::ipc::URIParams &aParams)
 {
   aParams = mozilla::ipc::NullPrincipalURIParams();
 }
--- a/image/decoders/icon/nsIconURI.cpp
+++ b/image/decoders/icon/nsIconURI.cpp
@@ -480,16 +480,29 @@ nsMozIconURI::GetAsciiHost(nsACString& a
 
 NS_IMETHODIMP
 nsMozIconURI::GetOriginCharset(nsACString& result)
 {
   result.Truncate();
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsMozIconURI::GetIsLocalRef(bool*)
+{
+    MOZ_ASSERT(false);
+    return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsMozIconURI::SetIsLocalRef(bool)
+{
+    MOZ_ASSERT(false);
+    return NS_ERROR_FAILURE;
+}
 ////////////////////////////////////////////////////////////////////////////////
 // nsIIconUri methods:
 
 NS_IMETHODIMP
 nsMozIconURI::GetIconURL(nsIURL** aFileUrl)
 {
   *aFileUrl = mIconURL;
   NS_IF_ADDREF(*aFileUrl);
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -8207,21 +8207,23 @@ CSSParserImpl::SetValueToURL(nsCSSValue&
       return true;
     }
 
     NS_NOTREACHED("Codepaths that expect to parse URLs MUST pass in an "
                   "origin principal");
     return false;
   }
 
+  bool isLocalRef = aURL.Length() ? (aURL.First() == '#') : false;
   RefPtr<nsStringBuffer> buffer(nsCSSValue::BufferFromString(aURL));
 
   // Note: urlVal retains its own reference to |buffer|.
   mozilla::css::URLValue *urlVal =
-    new mozilla::css::URLValue(buffer, mBaseURI, mSheetURI, mSheetPrincipal);
+    new mozilla::css::URLValue(buffer, mBaseURI, mSheetURI, mSheetPrincipal,
+                               isLocalRef);
   aValue.SetURLValue(urlVal);
   return true;
 }
 
 /**
  * Parse the image-orientation property, which has the grammar:
  * <angle> flip? | flip | from-image
  */
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -2490,22 +2490,24 @@ css::URLValue::URLValue(nsIURI* aURI, ns
     mReferrer(aReferrer),
     mOriginPrincipal(aOriginPrincipal),
     mURIResolved(true)
 {
   MOZ_ASSERT(aOriginPrincipal, "Must have an origin principal");
 }
 
 css::URLValue::URLValue(nsStringBuffer* aString, nsIURI* aBaseURI,
-                        nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
+                        nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal,
+                        bool aIsLocalRef)
   : mURI(aBaseURI),
     mString(aString),
     mReferrer(aReferrer),
     mOriginPrincipal(aOriginPrincipal),
-    mURIResolved(false)
+    mURIResolved(false),
+    mIsLocalRef(aIsLocalRef)
 {
   MOZ_ASSERT(aOriginPrincipal, "Must have an origin principal");
 }
 
 bool
 css::URLValue::operator==(const URLValue& aOther) const
 {
   bool eq;
@@ -2543,16 +2545,17 @@ css::URLValue::GetURI() const
   if (!mURIResolved) {
     mURIResolved = true;
     // Be careful to not null out mURI before we've passed it as the base URI
     nsCOMPtr<nsIURI> newURI;
     NS_NewURI(getter_AddRefs(newURI),
               NS_ConvertUTF16toUTF8(nsCSSValue::GetBufferValue(mString)),
               nullptr, mURI);
     newURI.swap(mURI);
+    mURI->SetIsLocalRef(mIsLocalRef);
   }
 
   return mURI;
 }
 
 size_t
 css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -90,17 +90,17 @@ struct URLValue {
   // caps, which leads to REQUIRES hell, since this header is included all
   // over.
 
   // For both constructors aString must not be null.
   // For both constructors aOriginPrincipal must not be null.
   // Construct with a base URI; this will create the actual URI lazily from
   // aString and aBaseURI.
   URLValue(nsStringBuffer* aString, nsIURI* aBaseURI, nsIURI* aReferrer,
-           nsIPrincipal* aOriginPrincipal);
+           nsIPrincipal* aOriginPrincipal, bool aIsLocalRef = false);
   // Construct with the actual URI.
   URLValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
            nsIPrincipal* aOriginPrincipal);
 
 protected:
   ~URLValue() {};
 
 public:
@@ -111,30 +111,32 @@ public:
   // mURI member of both URL objects is non-null.  Do NOT call this method
   // unless you're sure this is the case.
   bool URIEquals(const URLValue& aOther) const;
 
   nsIURI* GetURI() const;
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
+  bool IsLocalRef() const { return mIsLocalRef; }
 private:
   // If mURIResolved is false, mURI stores the base URI.
   // If mURIResolved is true, mURI stores the URI we resolve to; this may be
   // null if the URI is invalid.
   mutable nsCOMPtr<nsIURI> mURI;
 public:
   RefPtr<nsStringBuffer> mString;
   nsCOMPtr<nsIURI> mReferrer;
   nsCOMPtr<nsIPrincipal> mOriginPrincipal;
 
   NS_INLINE_DECL_REFCOUNTING(URLValue)
 
 private:
   mutable bool mURIResolved;
+  bool mIsLocalRef = false;
 
   URLValue(const URLValue& aOther) = delete;
   URLValue& operator=(const URLValue& aOther) = delete;
 };
 
 struct ImageValue : public URLValue {
   // Not making the constructor and destructor inline because that would
   // force us to include imgIRequest.h, which leads to REQUIRES hell, since
@@ -582,16 +584,24 @@ public:
   nsIURI* GetURLValue() const
   {
     MOZ_ASSERT(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
                "not a URL value");
     return mUnit == eCSSUnit_URL ?
       mValue.mURL->GetURI() : mValue.mImage->GetURI();
   }
 
+  bool IsLocalRefURL() const
+  {
+    MOZ_ASSERT(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
+               "not a URL value");
+    return mUnit == eCSSUnit_URL ?
+      mValue.mURL->IsLocalRef() : mValue.mImage->IsLocalRef();
+  }
+
   nsCSSValueGradient* GetGradientValue() const
   {
     MOZ_ASSERT(mUnit == eCSSUnit_Gradient, "not a gradient value");
     return mValue.mGradient;
   }
 
   nsCSSValueTokenStream* GetTokenStreamValue() const
   {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3235,17 +3235,19 @@ struct nsStyleSVGPaint
 {
   union {
     nscolor mColor;
     nsIURI *mPaintServer;
   } mPaint;
   nsStyleSVGPaintType mType;
   nscolor mFallbackColor;
 
-  nsStyleSVGPaint() : mType(nsStyleSVGPaintType(0)) { mPaint.mPaintServer = nullptr; }
+  nsStyleSVGPaint() : mType(nsStyleSVGPaintType(0)) {
+    mPaint.mPaintServer = nullptr;
+  }
   ~nsStyleSVGPaint();
   void SetType(nsStyleSVGPaintType aType);
   nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther);
   bool operator==(const nsStyleSVGPaint& aOther) const;
 
   bool operator!=(const nsStyleSVGPaint& aOther) const {
     return !(*this == aOther);
   }
--- a/modules/libjar/nsJARURI.cpp
+++ b/modules/libjar/nsJARURI.cpp
@@ -545,16 +545,28 @@ nsJARURI::Resolve(const nsACString &rela
     }
 
     nsAutoCString resolvedPath;
     mJAREntry->Resolve(relativePath, resolvedPath);
     
     return FormatSpec(resolvedPath, result);
 }
 
+NS_IMETHODIMP
+nsJARURI::GetIsLocalRef(bool*)
+{
+    return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsJARURI::SetIsLocalRef(bool)
+{
+    return NS_ERROR_FAILURE;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsIURL methods:
 
 NS_IMETHODIMP
 nsJARURI::GetFilePath(nsACString& filePath)
 {
     return mJAREntry->GetFilePath(filePath);
 }
--- a/netwerk/base/nsIURI.idl
+++ b/netwerk/base/nsIURI.idl
@@ -249,9 +249,11 @@ interface nsIURI : nsISupports
      * returns a string for the current URI with the ref element cleared.
      */
    readonly attribute AUTF8String specIgnoringRef;
 
     /**
      * Returns if there is a reference portion (the part after the "#") of the URI.
      */
    readonly attribute boolean hasRef;
+
+   attribute boolean IsLocalRef;
 };
--- a/netwerk/base/nsSimpleURI.cpp
+++ b/netwerk/base/nsSimpleURI.cpp
@@ -28,17 +28,18 @@ static NS_DEFINE_CID(kThisSimpleURIImple
                      NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsSimpleURI methods:
 
 nsSimpleURI::nsSimpleURI()
     : mMutable(true),
-      mIsRefValid(false)
+      mIsRefValid(false),
+      mIsLocalRef(false)
 {
 }
 
 nsSimpleURI::~nsSimpleURI()
 {
 }
 
 NS_IMPL_ADDREF(nsSimpleURI)
@@ -497,16 +498,17 @@ nsSimpleURI::CloneInternal(nsSimpleURI::
     RefPtr<nsSimpleURI> url = StartClone(refHandlingMode);
     if (!url)
         return NS_ERROR_OUT_OF_MEMORY;
 
     // Note: |url| may well have mMutable false at this point, so
     // don't call any setter methods.
     url->mScheme = mScheme;
     url->mPath = mPath;
+    url->mIsLocalRef = mIsLocalRef;
     if (refHandlingMode == eHonorRef) {
         url->mRef = mRef;
         url->mIsRefValid = mIsRefValid;
     }
 
     url.forget(result);
     return NS_OK;
 }
@@ -544,16 +546,32 @@ nsSimpleURI::GetAsciiHost(nsACString &re
 
 NS_IMETHODIMP
 nsSimpleURI::GetOriginCharset(nsACString &result)
 {
     result.Truncate();
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsSimpleURI::GetIsLocalRef(bool* result)
+{
+    NS_ENSURE_STATE(mMutable);
+    *result = mIsLocalRef;
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSimpleURI::SetIsLocalRef(bool input)
+{
+    mIsLocalRef = input;
+    return NS_OK;
+}
+
 //----------------------------------------------------------------------------
 // nsSimpleURI::nsIClassInfo
 //----------------------------------------------------------------------------
 
 NS_IMETHODIMP 
 nsSimpleURI::GetInterfaces(uint32_t *count, nsIID * **array)
 {
     *count = 0;
--- a/netwerk/base/nsSimpleURI.h
+++ b/netwerk/base/nsSimpleURI.h
@@ -81,11 +81,12 @@ protected:
     virtual nsresult CloneInternal(RefHandlingEnum refHandlingMode,
                                    nsIURI** clone);
     
     nsCString mScheme;
     nsCString mPath; // NOTE: mPath does not include ref, as an optimization
     nsCString mRef;  // so that URIs with different refs can share string data.
     bool mMutable;
     bool mIsRefValid; // To distinguish between empty-ref and no-ref.
+    bool mIsLocalRef;
 };
 
 #endif // nsSimpleURI_h__
--- a/netwerk/base/nsStandardURL.cpp
+++ b/netwerk/base/nsStandardURL.cpp
@@ -246,16 +246,17 @@ nsStandardURL::nsStandardURL(bool aSuppo
     : mDefaultPort(-1)
     , mPort(-1)
     , mHostA(nullptr)
     , mHostEncoding(eEncoding_ASCII)
     , mSpecEncoding(eEncoding_Unknown)
     , mURLType(URLTYPE_STANDARD)
     , mMutable(true)
     , mSupportsFileURL(aSupportsFileURL)
+    , mIsLocalRef(false)
 {
     LOG(("Creating nsStandardURL @%p\n", this));
 
     if (!gInitialized) {
         gInitialized = true;
         InitGlobalObjects();
     }
 
@@ -1182,16 +1183,30 @@ nsStandardURL::GetOriginCharset(nsACStri
 {
     if (mOriginCharset.IsEmpty())
         result.AssignLiteral("UTF-8");
     else
         result = mOriginCharset;
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsStandardURL::GetIsLocalRef(bool* result)
+{
+    *result = mIsLocalRef;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsStandardURL::SetIsLocalRef(bool input)
+{
+    mIsLocalRef = input;
+    return NS_OK;
+}
+
 static bool
 IsSpecialProtocol(const nsACString &input)
 {
     nsACString::const_iterator start, end;
     input.BeginReading(start);
     nsACString::const_iterator iterator(start);
     input.EndReading(end);
 
@@ -2017,16 +2032,17 @@ nsresult nsStandardURL::CopyMembers(nsSt
     mQuery = source->mQuery;
     mRef = source->mRef;
     mOriginCharset = source->mOriginCharset;
     mURLType = source->mURLType;
     mParser = source->mParser;
     mMutable = true;
     mSupportsFileURL = source->mSupportsFileURL;
     mHostEncoding = source->mHostEncoding;
+    mIsLocalRef = source->mIsLocalRef;
 
     if (copyCached) {
         mFile = source->mFile;
         mHostA = source->mHostA ? strdup(source->mHostA) : nullptr;
         mSpecEncoding = source->mSpecEncoding;
     } else {
         // The same state as after calling InvalidateCache()
         mFile = nullptr;
--- a/netwerk/base/nsStandardURL.h
+++ b/netwerk/base/nsStandardURL.h
@@ -276,16 +276,17 @@ private:
         eEncoding_UTF8
     };
 
     uint32_t mHostEncoding    : 2; // eEncoding_xxx
     uint32_t mSpecEncoding    : 2; // eEncoding_xxx
     uint32_t mURLType         : 2; // nsIStandardURL::URLTYPE_xxx
     uint32_t mMutable         : 1; // nsIStandardURL::mutable
     uint32_t mSupportsFileURL : 1; // QI to nsIFileURL?
+    uint32_t mIsLocalRef      : 1;
 
     // global objects.  don't use COMPtr as its destructor will cause a
     // coredump if we leak it.
     static nsIIDNService               *gIDN;
     static char                         gHostLimitDigits[];
     static bool                         gInitialized;
     static bool                         gEscapeUTF8;
     static bool                         gAlwaysEncodeInUTF8;