tor-browser

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

nsResProtocolHandler.cpp (6483B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      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/. */
      5 
      6 #include "mozilla/chrome/RegistryMessageUtils.h"
      7 #include "mozilla/dom/ContentParent.h"
      8 #include "mozilla/ClearOnShutdown.h"
      9 
     10 #include "nsResProtocolHandler.h"
     11 #include "nsNetCID.h"
     12 #include "nsNetUtil.h"
     13 #include "nsURLHelper.h"
     14 #include "nsEscape.h"
     15 
     16 #include "mozilla/Omnijar.h"
     17 
     18 using mozilla::LogLevel;
     19 using mozilla::dom::ContentParent;
     20 
     21 #define kAPP "app"
     22 #define kGRE "gre"
     23 #define kAndroid "android"
     24 
     25 mozilla::StaticRefPtr<nsResProtocolHandler> nsResProtocolHandler::sSingleton;
     26 
     27 already_AddRefed<nsResProtocolHandler> nsResProtocolHandler::GetSingleton() {
     28  if (!sSingleton) {
     29    RefPtr<nsResProtocolHandler> handler = new nsResProtocolHandler();
     30    if (NS_WARN_IF(NS_FAILED(handler->Init()))) {
     31      return nullptr;
     32    }
     33    sSingleton = handler;
     34    ClearOnShutdown(&sSingleton);
     35  }
     36  return do_AddRef(sSingleton);
     37 }
     38 
     39 nsresult nsResProtocolHandler::Init() {
     40  nsresult rv;
     41  rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::APP, mAppURI);
     42  NS_ENSURE_SUCCESS(rv, rv);
     43  rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::GRE, mGREURI);
     44  NS_ENSURE_SUCCESS(rv, rv);
     45 
     46  // mozilla::Omnijar::GetURIString always returns a string ending with /,
     47  // and we want to remove it.
     48  mGREURI.Truncate(mGREURI.Length() - 1);
     49  if (mAppURI.Length()) {
     50    mAppURI.Truncate(mAppURI.Length() - 1);
     51  } else {
     52    mAppURI = mGREURI;
     53  }
     54 
     55 #ifdef ANDROID
     56  rv = GetApkURI(mApkURI);
     57 #endif
     58 
     59  // XXXbsmedberg Neil wants a resource://pchrome/ for the profile chrome dir...
     60  // but once I finish multiple chrome registration I'm not sure that it is
     61  // needed
     62 
     63  // XXX dveditz: resource://pchrome/ defeats profile directory salting
     64  // if web content can load it. Tread carefully.
     65 
     66  return rv;
     67 }
     68 
     69 #ifdef ANDROID
     70 nsresult nsResProtocolHandler::GetApkURI(nsACString& aResult) {
     71  nsCString::const_iterator start, iter;
     72  mGREURI.BeginReading(start);
     73  mGREURI.EndReading(iter);
     74  nsCString::const_iterator start_iter = start;
     75 
     76  // This is like jar:jar:file://path/to/apk/base.apk!/path/to/omni.ja!/
     77  bool found = FindInReadable("!/"_ns, start_iter, iter);
     78  NS_ENSURE_TRUE(found, NS_ERROR_UNEXPECTED);
     79 
     80  // like jar:jar:file://path/to/apk/base.apk!/
     81  const nsDependentCSubstring& withoutPath = Substring(start, iter);
     82  NS_ENSURE_TRUE(withoutPath.Length() >= 4, NS_ERROR_UNEXPECTED);
     83 
     84  // Let's make sure we're removing what we expect to remove
     85  NS_ENSURE_TRUE(Substring(withoutPath, 0, 4).EqualsLiteral("jar:"),
     86                 NS_ERROR_UNEXPECTED);
     87 
     88  // like jar:file://path/to/apk/base.apk!/
     89  aResult = ToNewCString(Substring(withoutPath, 4));
     90 
     91  // Remove the trailing /
     92  NS_ENSURE_TRUE(aResult.Length() >= 1, NS_ERROR_UNEXPECTED);
     93  aResult.Truncate(aResult.Length() - 1);
     94  return NS_OK;
     95 }
     96 #endif
     97 
     98 //----------------------------------------------------------------------------
     99 // nsResProtocolHandler::nsISupports
    100 //----------------------------------------------------------------------------
    101 
    102 NS_IMPL_QUERY_INTERFACE(nsResProtocolHandler, nsIResProtocolHandler,
    103                        nsISubstitutingProtocolHandler, nsIProtocolHandler,
    104                        nsISupportsWeakReference)
    105 NS_IMPL_ADDREF_INHERITED(nsResProtocolHandler, SubstitutingProtocolHandler)
    106 NS_IMPL_RELEASE_INHERITED(nsResProtocolHandler, SubstitutingProtocolHandler)
    107 
    108 NS_IMETHODIMP
    109 nsResProtocolHandler::AllowContentToAccess(nsIURI* aURI, bool* aResult) {
    110  *aResult = false;
    111 
    112  nsAutoCString host;
    113  nsresult rv = aURI->GetAsciiHost(host);
    114  NS_ENSURE_SUCCESS(rv, rv);
    115 
    116  uint32_t flags;
    117  rv = GetSubstitutionFlags(host, &flags);
    118  NS_ENSURE_SUCCESS(rv, rv);
    119 
    120  *aResult = flags & nsISubstitutingProtocolHandler::ALLOW_CONTENT_ACCESS;
    121  return NS_OK;
    122 }
    123 
    124 uint32_t nsResProtocolHandler::GetJARFlags(const nsACString& aRoot) {
    125  if (aRoot.Equals(kAndroid)) {
    126    return nsISubstitutingProtocolHandler::RESOLVE_JAR_URI;
    127  }
    128 
    129  // 0 implies no content access.
    130  return 0;
    131 }
    132 
    133 nsresult nsResProtocolHandler::GetSubstitutionInternal(const nsACString& aRoot,
    134                                                       nsIURI** aResult) {
    135  nsAutoCString uri;
    136 
    137  if (!ResolveSpecialCases(aRoot, "/"_ns, "/"_ns, uri)) {
    138    return NS_ERROR_NOT_AVAILABLE;
    139  }
    140 
    141  return NS_NewURI(aResult, uri);
    142 }
    143 
    144 bool nsResProtocolHandler::ResolveSpecialCases(const nsACString& aHost,
    145                                               const nsACString& aPath,
    146                                               const nsACString& aPathname,
    147                                               nsACString& aResult) {
    148  if (aHost.EqualsLiteral("") || aHost.EqualsLiteral(kAPP)) {
    149    aResult.Assign(mAppURI);
    150  } else if (aHost.Equals(kGRE)) {
    151    aResult.Assign(mGREURI);
    152 #ifdef ANDROID
    153  } else if (aHost.Equals(kAndroid)) {
    154    aResult.Assign(mApkURI);
    155 #endif
    156  } else {
    157    return false;
    158  }
    159  aResult.Append(aPath);
    160  return true;
    161 }
    162 
    163 nsresult nsResProtocolHandler::SetSubstitution(const nsACString& aRoot,
    164                                               nsIURI* aBaseURI) {
    165  MOZ_ASSERT(!aRoot.EqualsLiteral(""));
    166  MOZ_ASSERT(!aRoot.EqualsLiteral(kAPP));
    167  MOZ_ASSERT(!aRoot.EqualsLiteral(kGRE));
    168  MOZ_ASSERT(!aRoot.EqualsLiteral(kAndroid));
    169  return SubstitutingProtocolHandler::SetSubstitution(aRoot, aBaseURI);
    170 }
    171 
    172 nsresult nsResProtocolHandler::SetSubstitutionWithFlags(const nsACString& aRoot,
    173                                                        nsIURI* aBaseURI,
    174                                                        uint32_t aFlags) {
    175  MOZ_ASSERT(!aRoot.EqualsLiteral(""));
    176  MOZ_ASSERT(!aRoot.EqualsLiteral(kAPP));
    177  MOZ_ASSERT(!aRoot.EqualsLiteral(kGRE));
    178  MOZ_ASSERT(!aRoot.EqualsLiteral(kAndroid));
    179  return SubstitutingProtocolHandler::SetSubstitutionWithFlags(aRoot, aBaseURI,
    180                                                               aFlags);
    181 }
    182 
    183 nsresult nsResProtocolHandler::HasSubstitution(const nsACString& aRoot,
    184                                               bool* aResult) {
    185  if (aRoot.EqualsLiteral(kAPP) || aRoot.EqualsLiteral(kGRE)
    186 #ifdef ANDROID
    187      || aRoot.EqualsLiteral(kAndroid)
    188 #endif
    189  ) {
    190    *aResult = true;
    191    return NS_OK;
    192  }
    193 
    194  return mozilla::net::SubstitutingProtocolHandler::HasSubstitution(aRoot,
    195                                                                    aResult);
    196 }