netwerk/base/src/nsSimpleURI.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "mozilla/DebugOnly.h"
     8 #undef LOG
     9 #include "IPCMessageUtils.h"
    11 #include "nsSimpleURI.h"
    12 #include "nscore.h"
    13 #include "nsString.h"
    14 #include "plstr.h"
    15 #include "nsURLHelper.h"
    16 #include "nsNetCID.h"
    17 #include "nsIObjectInputStream.h"
    18 #include "nsIObjectOutputStream.h"
    19 #include "nsEscape.h"
    20 #include "nsError.h"
    21 #include "nsIProgrammingLanguage.h"
    22 #include "nsIIPCSerializableURI.h"
    23 #include "mozilla/MemoryReporting.h"
    24 #include "mozilla/ipc/URIUtils.h"
    26 using namespace mozilla::ipc;
    28 static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
    29                      NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
    30 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
    32 ////////////////////////////////////////////////////////////////////////////////
    33 // nsSimpleURI methods:
    35 nsSimpleURI::nsSimpleURI()
    36     : mMutable(true),
    37       mIsRefValid(false)
    38 {
    39 }
    41 nsSimpleURI::~nsSimpleURI()
    42 {
    43 }
    45 NS_IMPL_ADDREF(nsSimpleURI)
    46 NS_IMPL_RELEASE(nsSimpleURI)
    47 NS_INTERFACE_TABLE_HEAD(nsSimpleURI)
    48 NS_INTERFACE_TABLE(nsSimpleURI, nsIURI, nsISerializable, nsIClassInfo,
    49                     nsIMutable, nsIIPCSerializableURI)
    50 NS_INTERFACE_TABLE_TO_MAP_SEGUE
    51   if (aIID.Equals(kThisSimpleURIImplementationCID))
    52     foundInterface = static_cast<nsIURI*>(this);
    53   else
    54   NS_INTERFACE_MAP_ENTRY(nsISizeOf)
    55 NS_INTERFACE_MAP_END
    57 ////////////////////////////////////////////////////////////////////////////////
    58 // nsISerializable methods:
    60 NS_IMETHODIMP
    61 nsSimpleURI::Read(nsIObjectInputStream* aStream)
    62 {
    63     nsresult rv;
    65     bool isMutable;
    66     rv = aStream->ReadBoolean(&isMutable);
    67     if (NS_FAILED(rv)) return rv;
    68     mMutable = isMutable;
    70     rv = aStream->ReadCString(mScheme);
    71     if (NS_FAILED(rv)) return rv;
    73     rv = aStream->ReadCString(mPath);
    74     if (NS_FAILED(rv)) return rv;
    76     bool isRefValid;
    77     rv = aStream->ReadBoolean(&isRefValid);
    78     if (NS_FAILED(rv)) return rv;
    79     mIsRefValid = isRefValid;
    81     if (isRefValid) {
    82         rv = aStream->ReadCString(mRef);
    83         if (NS_FAILED(rv)) return rv;
    84     } else {
    85         mRef.Truncate(); // invariant: mRef should be empty when it's not valid
    86     }
    88     return NS_OK;
    89 }
    91 NS_IMETHODIMP
    92 nsSimpleURI::Write(nsIObjectOutputStream* aStream)
    93 {
    94     nsresult rv;
    96     rv = aStream->WriteBoolean(mMutable);
    97     if (NS_FAILED(rv)) return rv;
    99     rv = aStream->WriteStringZ(mScheme.get());
   100     if (NS_FAILED(rv)) return rv;
   102     rv = aStream->WriteStringZ(mPath.get());
   103     if (NS_FAILED(rv)) return rv;
   105     rv = aStream->WriteBoolean(mIsRefValid);
   106     if (NS_FAILED(rv)) return rv;
   108     if (mIsRefValid) {
   109         rv = aStream->WriteStringZ(mRef.get());
   110         if (NS_FAILED(rv)) return rv;
   111     }
   113     return NS_OK;
   114 }
   116 ////////////////////////////////////////////////////////////////////////////////
   117 // nsIIPCSerializableURI methods:
   119 void
   120 nsSimpleURI::Serialize(URIParams& aParams)
   121 {
   122     SimpleURIParams params;
   124     params.scheme() = mScheme;
   125     params.path() = mPath;
   126     if (mIsRefValid) {
   127       params.ref() = mRef;
   128     }
   129     else {
   130       params.ref().SetIsVoid(true);
   131     }
   132     params.isMutable() = mMutable;
   134     aParams = params;
   135 }
   137 bool
   138 nsSimpleURI::Deserialize(const URIParams& aParams)
   139 {
   140     if (aParams.type() != URIParams::TSimpleURIParams) {
   141         NS_ERROR("Received unknown parameters from the other process!");
   142         return false;
   143     }
   145     const SimpleURIParams& params = aParams.get_SimpleURIParams();
   147     mScheme = params.scheme();
   148     mPath = params.path();
   149     if (params.ref().IsVoid()) {
   150         mRef.Truncate();
   151         mIsRefValid = false;
   152     }
   153     else {
   154         mRef = params.ref();
   155         mIsRefValid = true;
   156     }
   157     mMutable = params.isMutable();
   159     return true;
   160 }
   162 ////////////////////////////////////////////////////////////////////////////////
   163 // nsIURI methods:
   165 NS_IMETHODIMP
   166 nsSimpleURI::GetSpec(nsACString &result)
   167 {
   168     result = mScheme + NS_LITERAL_CSTRING(":") + mPath;
   169     if (mIsRefValid) {
   170         result += NS_LITERAL_CSTRING("#") + mRef;
   171     } else {
   172         NS_ABORT_IF_FALSE(mRef.IsEmpty(), "mIsRefValid/mRef invariant broken");
   173     }
   174     return NS_OK;
   175 }
   177 // result may contain unescaped UTF-8 characters
   178 NS_IMETHODIMP
   179 nsSimpleURI::GetSpecIgnoringRef(nsACString &result)
   180 {
   181     result = mScheme + NS_LITERAL_CSTRING(":") + mPath;
   182     return NS_OK;
   183 }
   185 NS_IMETHODIMP
   186 nsSimpleURI::GetHasRef(bool *result)
   187 {
   188     *result = mIsRefValid;
   189     return NS_OK;
   190 }
   192 NS_IMETHODIMP
   193 nsSimpleURI::SetSpec(const nsACString &aSpec)
   194 {
   195     NS_ENSURE_STATE(mMutable);
   197     const nsAFlatCString& flat = PromiseFlatCString(aSpec);
   198     const char* specPtr = flat.get();
   200     // filter out unexpected chars "\r\n\t" if necessary
   201     nsAutoCString filteredSpec;
   202     int32_t specLen;
   203     if (net_FilterURIString(specPtr, filteredSpec)) {
   204         specPtr = filteredSpec.get();
   205         specLen = filteredSpec.Length();
   206     } else
   207         specLen = flat.Length();
   209     // nsSimpleURI currently restricts the charset to US-ASCII
   210     nsAutoCString spec;
   211     NS_EscapeURL(specPtr, specLen, esc_OnlyNonASCII|esc_AlwaysCopy, spec);
   213     int32_t colonPos = spec.FindChar(':');
   214     if (colonPos < 0 || !net_IsValidScheme(spec.get(), colonPos))
   215         return NS_ERROR_MALFORMED_URI;
   217     mScheme.Truncate();
   218     mozilla::DebugOnly<int32_t> n = spec.Left(mScheme, colonPos);
   219     NS_ASSERTION(n == colonPos, "Left failed");
   220     ToLowerCase(mScheme);
   222     // This sets both mPath and mRef.
   223     return SetPath(Substring(spec, colonPos + 1));
   224 }
   226 NS_IMETHODIMP
   227 nsSimpleURI::GetScheme(nsACString &result)
   228 {
   229     result = mScheme;
   230     return NS_OK;
   231 }
   233 NS_IMETHODIMP
   234 nsSimpleURI::SetScheme(const nsACString &scheme)
   235 {
   236     NS_ENSURE_STATE(mMutable);
   238     const nsPromiseFlatCString &flat = PromiseFlatCString(scheme);
   239     if (!net_IsValidScheme(flat)) {
   240         NS_ERROR("the given url scheme contains invalid characters");
   241         return NS_ERROR_MALFORMED_URI;
   242     }
   244     mScheme = scheme;
   245     ToLowerCase(mScheme);
   246     return NS_OK;
   247 }
   249 NS_IMETHODIMP
   250 nsSimpleURI::GetPrePath(nsACString &result)
   251 {
   252     result = mScheme + NS_LITERAL_CSTRING(":");
   253     return NS_OK;
   254 }
   256 NS_IMETHODIMP
   257 nsSimpleURI::GetUserPass(nsACString &result)
   258 {
   259     return NS_ERROR_FAILURE;
   260 }
   262 NS_IMETHODIMP
   263 nsSimpleURI::SetUserPass(const nsACString &userPass)
   264 {
   265     NS_ENSURE_STATE(mMutable);
   267     return NS_ERROR_FAILURE;
   268 }
   270 NS_IMETHODIMP
   271 nsSimpleURI::GetUsername(nsACString &result)
   272 {
   273     return NS_ERROR_FAILURE;
   274 }
   276 NS_IMETHODIMP
   277 nsSimpleURI::SetUsername(const nsACString &userName)
   278 {
   279     NS_ENSURE_STATE(mMutable);
   281     return NS_ERROR_FAILURE;
   282 }
   284 NS_IMETHODIMP
   285 nsSimpleURI::GetPassword(nsACString &result)
   286 {
   287     return NS_ERROR_FAILURE;
   288 }
   290 NS_IMETHODIMP
   291 nsSimpleURI::SetPassword(const nsACString &password)
   292 {
   293     NS_ENSURE_STATE(mMutable);
   295     return NS_ERROR_FAILURE;
   296 }
   298 NS_IMETHODIMP
   299 nsSimpleURI::GetHostPort(nsACString &result)
   300 {
   301     // Note: Audit all callers before changing this to return an empty
   302     // string -- CAPS and UI code may depend on this throwing.
   303     return NS_ERROR_FAILURE;
   304 }
   306 NS_IMETHODIMP
   307 nsSimpleURI::SetHostPort(const nsACString &result)
   308 {
   309     NS_ENSURE_STATE(mMutable);
   311     return NS_ERROR_FAILURE;
   312 }
   314 NS_IMETHODIMP
   315 nsSimpleURI::GetHost(nsACString &result)
   316 {
   317     // Note: Audit all callers before changing this to return an empty
   318     // string -- CAPS and UI code depend on this throwing.
   319     return NS_ERROR_FAILURE;
   320 }
   322 NS_IMETHODIMP
   323 nsSimpleURI::SetHost(const nsACString &host)
   324 {
   325     NS_ENSURE_STATE(mMutable);
   327     return NS_ERROR_FAILURE;
   328 }
   330 NS_IMETHODIMP
   331 nsSimpleURI::GetPort(int32_t *result)
   332 {
   333     // Note: Audit all callers before changing this to return an empty
   334     // string -- CAPS and UI code may depend on this throwing.
   335     return NS_ERROR_FAILURE;
   336 }
   338 NS_IMETHODIMP
   339 nsSimpleURI::SetPort(int32_t port)
   340 {
   341     NS_ENSURE_STATE(mMutable);
   343     return NS_ERROR_FAILURE;
   344 }
   346 NS_IMETHODIMP
   347 nsSimpleURI::GetPath(nsACString &result)
   348 {
   349     result = mPath;
   350     if (mIsRefValid) {
   351         result += NS_LITERAL_CSTRING("#") + mRef;
   352     }
   354     return NS_OK;
   355 }
   357 NS_IMETHODIMP
   358 nsSimpleURI::SetPath(const nsACString &path)
   359 {
   360     NS_ENSURE_STATE(mMutable);
   362     int32_t hashPos = path.FindChar('#');
   363     if (hashPos < 0) {
   364         mIsRefValid = false;
   365         mRef.Truncate(); // invariant: mRef should be empty when it's not valid
   366         mPath = path;
   367         return NS_OK;
   368     }
   370     mPath = StringHead(path, hashPos);
   371     return SetRef(Substring(path, uint32_t(hashPos)));
   372 }
   374 NS_IMETHODIMP
   375 nsSimpleURI::GetRef(nsACString &result)
   376 {
   377     if (!mIsRefValid) {
   378       NS_ABORT_IF_FALSE(mRef.IsEmpty(), "mIsRefValid/mRef invariant broken");
   379       result.Truncate();
   380     } else {
   381       result = mRef;
   382     }
   384     return NS_OK;
   385 }
   387 // NOTE: SetRef("") removes our ref, whereas SetRef("#") sets it to the empty
   388 // string (and will result in .spec and .path having a terminal #).
   389 NS_IMETHODIMP
   390 nsSimpleURI::SetRef(const nsACString &aRef)
   391 {
   392     NS_ENSURE_STATE(mMutable);
   394     if (aRef.IsEmpty()) {
   395       // Empty string means to remove ref completely.
   396       mIsRefValid = false;
   397       mRef.Truncate(); // invariant: mRef should be empty when it's not valid
   398       return NS_OK;
   399     }
   401     mIsRefValid = true;
   403     // Gracefully skip initial hash
   404     if (aRef[0] == '#') {
   405         mRef = Substring(aRef, 1);
   406     } else {
   407         mRef = aRef;
   408     }
   410     return NS_OK;
   411 }
   413 NS_IMETHODIMP
   414 nsSimpleURI::Equals(nsIURI* other, bool *result)
   415 {
   416     return EqualsInternal(other, eHonorRef, result);
   417 }
   419 NS_IMETHODIMP
   420 nsSimpleURI::EqualsExceptRef(nsIURI* other, bool *result)
   421 {
   422     return EqualsInternal(other, eIgnoreRef, result);
   423 }
   425 /* virtual */ nsresult
   426 nsSimpleURI::EqualsInternal(nsIURI* other,
   427                             nsSimpleURI::RefHandlingEnum refHandlingMode,
   428                             bool* result)
   429 {
   430     NS_ENSURE_ARG_POINTER(other);
   431     NS_PRECONDITION(result, "null pointer");
   433     nsRefPtr<nsSimpleURI> otherUri;
   434     nsresult rv = other->QueryInterface(kThisSimpleURIImplementationCID,
   435                                         getter_AddRefs(otherUri));
   436     if (NS_FAILED(rv)) {
   437         *result = false;
   438         return NS_OK;
   439     }
   441     *result = EqualsInternal(otherUri, refHandlingMode);
   442     return NS_OK;
   443 }
   445 bool
   446 nsSimpleURI::EqualsInternal(nsSimpleURI* otherUri, RefHandlingEnum refHandlingMode)
   447 {
   448     bool result = (mScheme == otherUri->mScheme &&
   449                    mPath   == otherUri->mPath);
   451     if (result && refHandlingMode == eHonorRef) {
   452         result = (mIsRefValid == otherUri->mIsRefValid &&
   453                   (!mIsRefValid || mRef == otherUri->mRef));
   454     }
   456     return result;
   457 }
   459 NS_IMETHODIMP
   460 nsSimpleURI::SchemeIs(const char *i_Scheme, bool *o_Equals)
   461 {
   462     NS_ENSURE_ARG_POINTER(o_Equals);
   463     if (!i_Scheme) return NS_ERROR_NULL_POINTER;
   465     const char *this_scheme = mScheme.get();
   467     // mScheme is guaranteed to be lower case.
   468     if (*i_Scheme == *this_scheme || *i_Scheme == (*this_scheme - ('a' - 'A')) ) {
   469         *o_Equals = PL_strcasecmp(this_scheme, i_Scheme) ? false : true;
   470     } else {
   471         *o_Equals = false;
   472     }
   474     return NS_OK;
   475 }
   477 /* virtual */ nsSimpleURI*
   478 nsSimpleURI::StartClone(nsSimpleURI::RefHandlingEnum /* ignored */)
   479 {
   480     return new nsSimpleURI();
   481 }
   483 NS_IMETHODIMP
   484 nsSimpleURI::Clone(nsIURI** result)
   485 {
   486     return CloneInternal(eHonorRef, result);
   487 }
   489 NS_IMETHODIMP
   490 nsSimpleURI::CloneIgnoringRef(nsIURI** result)
   491 {
   492     return CloneInternal(eIgnoreRef, result);
   493 }
   495 nsresult
   496 nsSimpleURI::CloneInternal(nsSimpleURI::RefHandlingEnum refHandlingMode,
   497                            nsIURI** result)
   498 {
   499     nsRefPtr<nsSimpleURI> url = StartClone(refHandlingMode);
   500     if (!url)
   501         return NS_ERROR_OUT_OF_MEMORY;
   503     // Note: |url| may well have mMutable false at this point, so
   504     // don't call any setter methods.
   505     url->mScheme = mScheme;
   506     url->mPath = mPath;
   507     if (refHandlingMode == eHonorRef) {
   508         url->mRef = mRef;
   509         url->mIsRefValid = mIsRefValid;
   510     }
   512     url.forget(result);
   513     return NS_OK;
   514 }
   516 NS_IMETHODIMP
   517 nsSimpleURI::Resolve(const nsACString &relativePath, nsACString &result) 
   518 {
   519     result = relativePath;
   520     return NS_OK;
   521 }
   523 NS_IMETHODIMP
   524 nsSimpleURI::GetAsciiSpec(nsACString &result)
   525 {
   526     nsAutoCString buf;
   527     nsresult rv = GetSpec(buf);
   528     if (NS_FAILED(rv)) return rv;
   529     NS_EscapeURL(buf, esc_OnlyNonASCII|esc_AlwaysCopy, result);
   530     return NS_OK;
   531 }
   533 NS_IMETHODIMP
   534 nsSimpleURI::GetAsciiHost(nsACString &result)
   535 {
   536     result.Truncate();
   537     return NS_OK;
   538 }
   540 NS_IMETHODIMP
   541 nsSimpleURI::GetOriginCharset(nsACString &result)
   542 {
   543     result.Truncate();
   544     return NS_OK;
   545 }
   547 //----------------------------------------------------------------------------
   548 // nsSimpleURI::nsIClassInfo
   549 //----------------------------------------------------------------------------
   551 NS_IMETHODIMP 
   552 nsSimpleURI::GetInterfaces(uint32_t *count, nsIID * **array)
   553 {
   554     *count = 0;
   555     *array = nullptr;
   556     return NS_OK;
   557 }
   559 NS_IMETHODIMP 
   560 nsSimpleURI::GetHelperForLanguage(uint32_t language, nsISupports **_retval)
   561 {
   562     *_retval = nullptr;
   563     return NS_OK;
   564 }
   566 NS_IMETHODIMP 
   567 nsSimpleURI::GetContractID(char * *aContractID)
   568 {
   569     // Make sure to modify any subclasses as needed if this ever
   570     // changes.
   571     *aContractID = nullptr;
   572     return NS_OK;
   573 }
   575 NS_IMETHODIMP 
   576 nsSimpleURI::GetClassDescription(char * *aClassDescription)
   577 {
   578     *aClassDescription = nullptr;
   579     return NS_OK;
   580 }
   582 NS_IMETHODIMP 
   583 nsSimpleURI::GetClassID(nsCID * *aClassID)
   584 {
   585     // Make sure to modify any subclasses as needed if this ever
   586     // changes to not call the virtual GetClassIDNoAlloc.
   587     *aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
   588     if (!*aClassID)
   589         return NS_ERROR_OUT_OF_MEMORY;
   590     return GetClassIDNoAlloc(*aClassID);
   591 }
   593 NS_IMETHODIMP 
   594 nsSimpleURI::GetImplementationLanguage(uint32_t *aImplementationLanguage)
   595 {
   596     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
   597     return NS_OK;
   598 }
   600 NS_IMETHODIMP 
   601 nsSimpleURI::GetFlags(uint32_t *aFlags)
   602 {
   603     *aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
   604     return NS_OK;
   605 }
   607 NS_IMETHODIMP 
   608 nsSimpleURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
   609 {
   610     *aClassIDNoAlloc = kSimpleURICID;
   611     return NS_OK;
   612 }
   614 //----------------------------------------------------------------------------
   615 // nsSimpleURI::nsISimpleURI
   616 //----------------------------------------------------------------------------
   617 NS_IMETHODIMP
   618 nsSimpleURI::GetMutable(bool *value)
   619 {
   620     *value = mMutable;
   621     return NS_OK;
   622 }
   624 NS_IMETHODIMP
   625 nsSimpleURI::SetMutable(bool value)
   626 {
   627     NS_ENSURE_ARG(mMutable || !value);
   629     mMutable = value;
   630     return NS_OK;
   631 }
   633 //----------------------------------------------------------------------------
   634 // nsSimpleURI::nsISizeOf
   635 //----------------------------------------------------------------------------
   637 size_t 
   638 nsSimpleURI::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
   639 {
   640   return mScheme.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
   641          mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
   642          mRef.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
   643 }
   645 size_t
   646 nsSimpleURI::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
   647   return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   648 }

mercurial