tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DefaultURI.cpp (16520B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "DefaultURI.h"
      6 #include "nsIClassInfoImpl.h"
      7 #include "nsIObjectInputStream.h"
      8 #include "nsIObjectOutputStream.h"
      9 #include "nsURLHelper.h"
     10 #include "urlpattern_glue/URLPatternGlue.h"
     11 
     12 #include "mozilla/ipc/URIParams.h"
     13 
     14 namespace mozilla {
     15 namespace net {
     16 
     17 #define NS_DEFAULTURI_CID                     \
     18  {/* 04445aa0-fd27-4c99-bd41-6be6318ae92c */ \
     19   0x04445aa0,                                \
     20   0xfd27,                                    \
     21   0x4c99,                                    \
     22   {0xbd, 0x41, 0x6b, 0xe6, 0x31, 0x8a, 0xe9, 0x2c}}
     23 
     24 #define ASSIGN_AND_ADDREF_THIS(ptrToMutator)    \
     25  do {                                          \
     26    if (ptrToMutator) {                         \
     27      *(ptrToMutator) = do_AddRef(this).take(); \
     28    }                                           \
     29  } while (0)
     30 
     31 static NS_DEFINE_CID(kDefaultURICID, NS_DEFAULTURI_CID);
     32 
     33 //----------------------------------------------------------------------------
     34 // nsIClassInfo
     35 //----------------------------------------------------------------------------
     36 
     37 NS_IMPL_CLASSINFO(DefaultURI, nullptr, nsIClassInfo::THREADSAFE,
     38                  NS_DEFAULTURI_CID)
     39 // Empty CI getter. We only need nsIClassInfo for Serialization
     40 NS_IMPL_CI_INTERFACE_GETTER0(DefaultURI)
     41 
     42 //----------------------------------------------------------------------------
     43 // nsISupports
     44 //----------------------------------------------------------------------------
     45 
     46 NS_IMPL_ADDREF(DefaultURI)
     47 NS_IMPL_RELEASE(DefaultURI)
     48 NS_INTERFACE_TABLE_HEAD(DefaultURI)
     49  NS_INTERFACE_TABLE(DefaultURI, nsIURI, nsISerializable)
     50  NS_INTERFACE_TABLE_TO_MAP_SEGUE
     51  NS_IMPL_QUERY_CLASSINFO(DefaultURI)
     52  if (aIID.Equals(kDefaultURICID)) {
     53    foundInterface = static_cast<nsIURI*>(this);
     54  } else
     55 NS_INTERFACE_MAP_END
     56 
     57 //----------------------------------------------------------------------------
     58 // nsISerializable
     59 //----------------------------------------------------------------------------
     60 
     61 NS_IMETHODIMP DefaultURI::Read(nsIObjectInputStream* aInputStream) {
     62  MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
     63  return NS_ERROR_NOT_IMPLEMENTED;
     64 }
     65 
     66 NS_IMETHODIMP DefaultURI::Write(nsIObjectOutputStream* aOutputStream) {
     67  nsAutoCString spec(mURL->Spec());
     68  return aOutputStream->WriteStringZ(spec.get());
     69 }
     70 
     71 //----------------------------------------------------------------------------
     72 // nsIURI
     73 //----------------------------------------------------------------------------
     74 
     75 NS_IMETHODIMP DefaultURI::GetSpec(nsACString& aSpec) {
     76  aSpec = mURL->Spec();
     77  return NS_OK;
     78 }
     79 
     80 NS_IMETHODIMP DefaultURI::GetPrePath(nsACString& aPrePath) {
     81  aPrePath = mURL->PrePath();
     82  return NS_OK;
     83 }
     84 
     85 NS_IMETHODIMP DefaultURI::GetScheme(nsACString& aScheme) {
     86  aScheme = mURL->Scheme();
     87  return NS_OK;
     88 }
     89 
     90 NS_IMETHODIMP DefaultURI::GetUserPass(nsACString& aUserPass) {
     91  aUserPass = mURL->Username();
     92  nsAutoCString pass(mURL->Password());
     93  if (pass.IsEmpty()) {
     94    return NS_OK;
     95  }
     96  aUserPass.Append(':');
     97  aUserPass.Append(pass);
     98  return NS_OK;
     99 }
    100 
    101 NS_IMETHODIMP DefaultURI::GetUsername(nsACString& aUsername) {
    102  aUsername = mURL->Username();
    103  return NS_OK;
    104 }
    105 
    106 NS_IMETHODIMP DefaultURI::GetPassword(nsACString& aPassword) {
    107  aPassword = mURL->Password();
    108  return NS_OK;
    109 }
    110 
    111 NS_IMETHODIMP DefaultURI::GetHostPort(nsACString& aHostPort) {
    112  aHostPort = mURL->HostPort();
    113  return NS_OK;
    114 }
    115 
    116 NS_IMETHODIMP DefaultURI::GetHost(nsACString& aHost) {
    117  aHost = mURL->Host();
    118 
    119  // Historically nsIURI.host has always returned an IPv6 address that isn't
    120  // enclosed in brackets. Ideally we want to change that, but for the sake of
    121  // consitency we'll leave it like that for the moment.
    122  // Bug 1603199 should fix this.
    123  if (StringBeginsWith(aHost, "["_ns) && StringEndsWith(aHost, "]"_ns) &&
    124      aHost.FindChar(':') != kNotFound) {
    125    aHost = Substring(aHost, 1, aHost.Length() - 2);
    126  }
    127  return NS_OK;
    128 }
    129 
    130 NS_IMETHODIMP DefaultURI::GetPort(int32_t* aPort) {
    131  *aPort = mURL->Port();
    132  return NS_OK;
    133 }
    134 
    135 NS_IMETHODIMP DefaultURI::GetPathQueryRef(nsACString& aPathQueryRef) {
    136  aPathQueryRef = mURL->Path();
    137  return NS_OK;
    138 }
    139 
    140 NS_IMETHODIMP DefaultURI::Equals(nsIURI* other, bool* _retval) {
    141  if (!other) {
    142    *_retval = false;
    143    return NS_OK;
    144  }
    145  RefPtr<DefaultURI> otherUri;
    146  nsresult rv = other->QueryInterface(kDefaultURICID, getter_AddRefs(otherUri));
    147  if (NS_FAILED(rv)) {
    148    *_retval = false;
    149    return NS_OK;
    150  }
    151 
    152  *_retval = mURL->Spec() == otherUri->mURL->Spec();
    153  return NS_OK;
    154 }
    155 
    156 NS_IMETHODIMP DefaultURI::SchemeIs(const char* scheme, bool* _retval) {
    157  if (!scheme) {
    158    *_retval = false;
    159    return NS_OK;
    160  }
    161  *_retval = mURL->Scheme().Equals(scheme);
    162  return NS_OK;
    163 }
    164 
    165 NS_IMETHODIMP DefaultURI::Resolve(const nsACString& aRelativePath,
    166                                  nsACString& aResult) {
    167  nsAutoCString scheme;
    168  nsresult rv = net_ExtractURLScheme(aRelativePath, scheme);
    169  if (NS_SUCCEEDED(rv)) {
    170    aResult = aRelativePath;
    171    return NS_OK;
    172  }
    173 
    174  // We try to create another URL with this one as its base.
    175  RefPtr<MozURL> resolvedURL;
    176  rv = MozURL::Init(getter_AddRefs(resolvedURL), aRelativePath, mURL);
    177  if (NS_WARN_IF(NS_FAILED(rv))) {
    178    // If parsing the relative url fails, we revert to the previous behaviour
    179    // and just return the relative path.
    180    aResult = aRelativePath;
    181    return NS_OK;
    182  }
    183 
    184  aResult = resolvedURL->Spec();
    185  return NS_OK;
    186 }
    187 
    188 NS_IMETHODIMP DefaultURI::GetAsciiSpec(nsACString& aAsciiSpec) {
    189  return GetSpec(aAsciiSpec);
    190 }
    191 
    192 NS_IMETHODIMP DefaultURI::GetAsciiHostPort(nsACString& aAsciiHostPort) {
    193  return GetHostPort(aAsciiHostPort);
    194 }
    195 
    196 NS_IMETHODIMP DefaultURI::GetAsciiHost(nsACString& aAsciiHost) {
    197  return GetHost(aAsciiHost);
    198 }
    199 
    200 NS_IMETHODIMP DefaultURI::GetRef(nsACString& aRef) {
    201  aRef = mURL->Ref();
    202  return NS_OK;
    203 }
    204 
    205 NS_IMETHODIMP DefaultURI::EqualsExceptRef(nsIURI* other, bool* _retval) {
    206  if (!_retval || !other) {
    207    return NS_ERROR_NULL_POINTER;
    208  }
    209  RefPtr<DefaultURI> otherUri;
    210  nsresult rv = other->QueryInterface(kDefaultURICID, getter_AddRefs(otherUri));
    211  if (NS_FAILED(rv)) {
    212    *_retval = false;
    213    return NS_OK;
    214  }
    215 
    216  *_retval = mURL->SpecNoRef().Equals(otherUri->mURL->SpecNoRef());
    217  return NS_OK;
    218 }
    219 
    220 NS_IMETHODIMP DefaultURI::GetSpecIgnoringRef(nsACString& aSpecIgnoringRef) {
    221  aSpecIgnoringRef = mURL->SpecNoRef();
    222  return NS_OK;
    223 }
    224 
    225 NS_IMETHODIMP DefaultURI::GetHasRef(bool* aHasRef) {
    226  *aHasRef = mURL->HasFragment();
    227  return NS_OK;
    228 }
    229 
    230 NS_IMETHODIMP DefaultURI::GetHasUserPass(bool* aHasUserPass) {
    231  *aHasUserPass = !mURL->Username().IsEmpty() || !mURL->Password().IsEmpty();
    232  return NS_OK;
    233 }
    234 
    235 NS_IMETHODIMP DefaultURI::GetFilePath(nsACString& aFilePath) {
    236  aFilePath = mURL->FilePath();
    237  return NS_OK;
    238 }
    239 
    240 NS_IMETHODIMP DefaultURI::GetQuery(nsACString& aQuery) {
    241  aQuery = mURL->Query();
    242  return NS_OK;
    243 }
    244 
    245 NS_IMETHODIMP DefaultURI::GetHasQuery(bool* aHasQuery) {
    246  *aHasQuery = mURL->HasQuery();
    247  return NS_OK;
    248 }
    249 
    250 NS_IMETHODIMP DefaultURI::GetDisplayHost(nsACString& aDisplayHost) {
    251  // At the moment it doesn't seem useful to decode the hostname if it happens
    252  // to contain punycode.
    253  return GetHost(aDisplayHost);
    254 }
    255 
    256 NS_IMETHODIMP DefaultURI::GetDisplayHostPort(nsACString& aDisplayHostPort) {
    257  // At the moment it doesn't seem useful to decode the hostname if it happens
    258  // to contain punycode.
    259  return GetHostPort(aDisplayHostPort);
    260 }
    261 
    262 NS_IMETHODIMP DefaultURI::GetDisplaySpec(nsACString& aDisplaySpec) {
    263  // At the moment it doesn't seem useful to decode the hostname if it happens
    264  // to contain punycode.
    265  return GetSpec(aDisplaySpec);
    266 }
    267 
    268 NS_IMETHODIMP DefaultURI::GetDisplayPrePath(nsACString& aDisplayPrePath) {
    269  // At the moment it doesn't seem useful to decode the hostname if it happens
    270  // to contain punycode.
    271  return GetPrePath(aDisplayPrePath);
    272 }
    273 
    274 NS_IMETHODIMP DefaultURI::Mutate(nsIURIMutator** _retval) {
    275  RefPtr<DefaultURI::Mutator> mutator = new DefaultURI::Mutator();
    276  mutator->Init(this);
    277  mutator.forget(_retval);
    278  return NS_OK;
    279 }
    280 
    281 void DefaultURI::Serialize(ipc::URIParams& aParams) {
    282  ipc::DefaultURIParams params;
    283  params.spec() = mURL->Spec();
    284  aParams = params;
    285 }
    286 
    287 size_t DefaultURI::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) {
    288  return aMallocSizeOf(this) + mURL->SizeOf();
    289 }
    290 
    291 //----------------------------------------------------------------------------
    292 // nsIURIMutator
    293 //----------------------------------------------------------------------------
    294 
    295 NS_IMPL_ADDREF(DefaultURI::Mutator)
    296 NS_IMPL_RELEASE(DefaultURI::Mutator)
    297 NS_IMETHODIMP DefaultURI::Mutator::QueryInterface(REFNSIID aIID,
    298                                                  void** aInstancePtr) {
    299  NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!");
    300  nsISupports* foundInterface = nullptr;
    301  if (aIID.Equals(NS_GET_IID(nsIURI))) {
    302    RefPtr<DefaultURI> defaultURI = new DefaultURI();
    303    mMutator->Finalize(getter_AddRefs(defaultURI->mURL));
    304    foundInterface =
    305        static_cast<nsISupports*>(static_cast<nsIURI*>((defaultURI.get())));
    306    NS_ADDREF(foundInterface);
    307    *aInstancePtr = foundInterface;
    308    return NS_OK;
    309  }
    310 
    311  if (aIID.Equals(NS_GET_IID(nsIURIMutator)) ||
    312      aIID.Equals(NS_GET_IID(nsISupports))) {
    313    foundInterface =
    314        static_cast<nsISupports*>(static_cast<nsIURIMutator*>(this));
    315  } else if (aIID.Equals(NS_GET_IID(nsIURISetters))) {
    316    foundInterface =
    317        static_cast<nsISupports*>(static_cast<nsIURISetters*>(this));
    318  } else if (aIID.Equals(NS_GET_IID(nsIURISetSpec))) {
    319    foundInterface =
    320        static_cast<nsISupports*>(static_cast<nsIURISetSpec*>(this));
    321  } else if (aIID.Equals(NS_GET_IID(nsISerializable))) {
    322    foundInterface =
    323        static_cast<nsISupports*>(static_cast<nsISerializable*>(this));
    324  }
    325 
    326  if (foundInterface) {
    327    NS_ADDREF(foundInterface);
    328    *aInstancePtr = foundInterface;
    329    return NS_OK;
    330  }
    331 
    332  return NS_NOINTERFACE;
    333 }
    334 
    335 NS_IMETHODIMP DefaultURI::Mutator::Read(nsIObjectInputStream* aStream) {
    336  nsAutoCString spec;
    337  nsresult rv = aStream->ReadCString(spec);
    338  if (NS_FAILED(rv)) {
    339    return rv;
    340  }
    341  return SetSpec(spec, nullptr);
    342 }
    343 
    344 NS_IMETHODIMP DefaultURI::Mutator::Deserialize(
    345    const mozilla::ipc::URIParams& aParams) {
    346  if (aParams.type() != ipc::URIParams::TDefaultURIParams) {
    347    NS_ERROR("Received unknown parameters from the other process!");
    348    return NS_ERROR_FAILURE;
    349  }
    350 
    351  const ipc::DefaultURIParams& params = aParams.get_DefaultURIParams();
    352  auto result = MozURL::Mutator::FromSpec(params.spec());
    353  if (result.isErr()) {
    354    return result.unwrapErr();
    355  }
    356  mMutator = Some(result.unwrap());
    357  return NS_OK;
    358 }
    359 
    360 NS_IMETHODIMP DefaultURI::Mutator::Finalize(nsIURI** aURI) {
    361  if (!mMutator.isSome()) {
    362    return NS_ERROR_NOT_AVAILABLE;
    363  }
    364  RefPtr<DefaultURI> uri = new DefaultURI();
    365  mMutator->Finalize(getter_AddRefs(uri->mURL));
    366  mMutator = Nothing();
    367  uri.forget(aURI);
    368  return NS_OK;
    369 }
    370 
    371 NS_IMETHODIMP DefaultURI::Mutator::SetSpec(const nsACString& aSpec,
    372                                           nsIURIMutator** aMutator) {
    373  ASSIGN_AND_ADDREF_THIS(aMutator);
    374  auto result = MozURL::Mutator::FromSpec(aSpec);
    375  if (result.isErr()) {
    376    return result.unwrapErr();
    377  }
    378  mMutator = Some(result.unwrap());
    379  return NS_OK;
    380 }
    381 
    382 NS_IMETHODIMP
    383 DefaultURI::Mutator::SetScheme(const nsACString& aScheme,
    384                               nsIURIMutator** aMutator) {
    385  ASSIGN_AND_ADDREF_THIS(aMutator);
    386  if (!mMutator.isSome()) {
    387    return NS_ERROR_NULL_POINTER;
    388  }
    389  mMutator->SetScheme(aScheme);
    390  return mMutator->GetStatus();
    391 }
    392 
    393 NS_IMETHODIMP
    394 DefaultURI::Mutator::SetUserPass(const nsACString& aUserPass,
    395                                 nsIURIMutator** aMutator) {
    396  ASSIGN_AND_ADDREF_THIS(aMutator);
    397  if (!mMutator.isSome()) {
    398    return NS_ERROR_NULL_POINTER;
    399  }
    400  int32_t index = aUserPass.FindChar(':');
    401  if (index == kNotFound) {
    402    mMutator->SetUsername(aUserPass);
    403    mMutator->SetPassword(""_ns);
    404    return mMutator->GetStatus();
    405  }
    406 
    407  mMutator->SetUsername(Substring(aUserPass, 0, index));
    408  nsresult rv = mMutator->GetStatus();
    409  if (NS_FAILED(rv)) {
    410    return rv;
    411  }
    412  mMutator->SetPassword(Substring(aUserPass, index + 1));
    413  rv = mMutator->GetStatus();
    414  if (NS_FAILED(rv)) {
    415    return rv;
    416  }
    417  return NS_OK;
    418 }
    419 
    420 NS_IMETHODIMP
    421 DefaultURI::Mutator::SetUsername(const nsACString& aUsername,
    422                                 nsIURIMutator** aMutator) {
    423  ASSIGN_AND_ADDREF_THIS(aMutator);
    424  if (!mMutator.isSome()) {
    425    return NS_ERROR_NULL_POINTER;
    426  }
    427  mMutator->SetUsername(aUsername);
    428  return mMutator->GetStatus();
    429 }
    430 
    431 NS_IMETHODIMP
    432 DefaultURI::Mutator::SetPassword(const nsACString& aPassword,
    433                                 nsIURIMutator** aMutator) {
    434  ASSIGN_AND_ADDREF_THIS(aMutator);
    435  if (!mMutator.isSome()) {
    436    return NS_ERROR_NULL_POINTER;
    437  }
    438  mMutator->SetPassword(aPassword);
    439  return mMutator->GetStatus();
    440 }
    441 
    442 NS_IMETHODIMP
    443 DefaultURI::Mutator::SetHostPort(const nsACString& aHostPort,
    444                                 nsIURIMutator** aMutator) {
    445  ASSIGN_AND_ADDREF_THIS(aMutator);
    446  if (!mMutator.isSome()) {
    447    return NS_ERROR_NULL_POINTER;
    448  }
    449  mMutator->SetHostPort(aHostPort);
    450  return mMutator->GetStatus();
    451 }
    452 
    453 NS_IMETHODIMP
    454 DefaultURI::Mutator::SetHost(const nsACString& aHost,
    455                             nsIURIMutator** aMutator) {
    456  ASSIGN_AND_ADDREF_THIS(aMutator);
    457  if (!mMutator.isSome()) {
    458    return NS_ERROR_NULL_POINTER;
    459  }
    460  mMutator->SetHostname(aHost);
    461  return mMutator->GetStatus();
    462 }
    463 
    464 NS_IMETHODIMP
    465 DefaultURI::Mutator::SetPort(int32_t aPort, nsIURIMutator** aMutator) {
    466  ASSIGN_AND_ADDREF_THIS(aMutator);
    467  if (!mMutator.isSome()) {
    468    return NS_ERROR_NULL_POINTER;
    469  }
    470  mMutator->SetPort(aPort);
    471  return mMutator->GetStatus();
    472 }
    473 
    474 NS_IMETHODIMP
    475 DefaultURI::Mutator::SetPathQueryRef(const nsACString& aPathQueryRef,
    476                                     nsIURIMutator** aMutator) {
    477  ASSIGN_AND_ADDREF_THIS(aMutator);
    478  if (!mMutator.isSome()) {
    479    return NS_ERROR_NULL_POINTER;
    480  }
    481  if (aPathQueryRef.IsEmpty()) {
    482    mMutator->SetFilePath(""_ns);
    483    mMutator->SetQuery(""_ns);
    484    mMutator->SetRef(""_ns);
    485    return mMutator->GetStatus();
    486  }
    487 
    488  RefPtr<MozURL> url;
    489  mMutator->Finalize(getter_AddRefs(url));
    490  mMutator = Nothing();
    491 
    492  if (!url) {
    493    return NS_ERROR_FAILURE;
    494  }
    495 
    496  nsAutoCString pathQueryRef(aPathQueryRef);
    497  if (url->CannotBeABase()) {
    498    // If the base URL cannot be a base, then setting the pathQueryRef
    499    // needs to change everything after the scheme.
    500    pathQueryRef.Insert(":", 0);
    501    pathQueryRef.Insert(url->Scheme(), 0);
    502    // Clear the URL to make sure FromSpec creates an absolute URL
    503    url = nullptr;
    504  } else if (!StringBeginsWith(pathQueryRef, "/"_ns)) {
    505    // If the base URL can be a base, make sure the path
    506    // begins with a /
    507    pathQueryRef.Insert('/', 0);
    508  }
    509 
    510  auto result = MozURL::Mutator::FromSpec(pathQueryRef, url);
    511  if (result.isErr()) {
    512    return result.unwrapErr();
    513  }
    514  mMutator = Some(result.unwrap());
    515  return mMutator->GetStatus();
    516 }
    517 
    518 NS_IMETHODIMP
    519 DefaultURI::Mutator::SetRef(const nsACString& aRef, nsIURIMutator** aMutator) {
    520  ASSIGN_AND_ADDREF_THIS(aMutator);
    521  if (!mMutator.isSome()) {
    522    return NS_ERROR_NULL_POINTER;
    523  }
    524  mMutator->SetRef(aRef);
    525  return mMutator->GetStatus();
    526 }
    527 
    528 NS_IMETHODIMP
    529 DefaultURI::Mutator::SetFilePath(const nsACString& aFilePath,
    530                                 nsIURIMutator** aMutator) {
    531  ASSIGN_AND_ADDREF_THIS(aMutator);
    532  if (!mMutator.isSome()) {
    533    return NS_ERROR_NULL_POINTER;
    534  }
    535  mMutator->SetFilePath(aFilePath);
    536  return mMutator->GetStatus();
    537 }
    538 
    539 NS_IMETHODIMP
    540 DefaultURI::Mutator::SetQuery(const nsACString& aQuery,
    541                              nsIURIMutator** aMutator) {
    542  ASSIGN_AND_ADDREF_THIS(aMutator);
    543  if (!mMutator.isSome()) {
    544    return NS_ERROR_NULL_POINTER;
    545  }
    546  mMutator->SetQuery(aQuery);
    547  return mMutator->GetStatus();
    548 }
    549 
    550 NS_IMETHODIMP
    551 DefaultURI::Mutator::SetQueryWithEncoding(const nsACString& aQuery,
    552                                          const mozilla::Encoding* aEncoding,
    553                                          nsIURIMutator** aMutator) {
    554  ASSIGN_AND_ADDREF_THIS(aMutator);
    555  if (!mMutator.isSome()) {
    556    return NS_ERROR_NULL_POINTER;
    557  }
    558  // we only support UTF-8 for DefaultURI
    559  mMutator->SetQuery(aQuery);
    560  return mMutator->GetStatus();
    561 }
    562 
    563 }  // namespace net
    564 }  // namespace mozilla