tor-browser

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

nsIconURI.cpp (16828B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set sw=2 sts=2 ts=2 et tw=80:
      3 *
      4 * This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #include "nsIconURI.h"
      9 
     10 #include "mozilla/ipc/URIUtils.h"
     11 #include "mozilla/Sprintf.h"
     12 
     13 #include "nsIClassInfoImpl.h"
     14 #include "nsIIOService.h"
     15 #include "nsISerializable.h"
     16 #include "nsIObjectInputStream.h"
     17 #include "nsIObjectOutputStream.h"
     18 #include "nsIURL.h"
     19 #include "nsNetUtil.h"
     20 #include "plstr.h"
     21 #include "nsCRT.h"
     22 #include <stdlib.h>
     23 
     24 using namespace mozilla;
     25 using namespace mozilla::ipc;
     26 
     27 #define DEFAULT_IMAGE_SIZE 16
     28 
     29 #if defined(MAX_PATH)
     30 #  define SANE_FILE_NAME_LEN MAX_PATH
     31 #elif defined(PATH_MAX)
     32 #  define SANE_FILE_NAME_LEN PATH_MAX
     33 #else
     34 #  define SANE_FILE_NAME_LEN 1024
     35 #endif
     36 
     37 static NS_DEFINE_CID(kThisIconURIImplementationCID,
     38                     NS_THIS_ICONURI_IMPLEMENTATION_CID);
     39 
     40 ////////////////////////////////////////////////////////////////////////////////
     41 
     42 NS_IMPL_CLASSINFO(nsMozIconURI, nullptr, nsIClassInfo::THREADSAFE,
     43                  NS_ICONURI_CID)
     44 // Empty CI getter. We only need nsIClassInfo for Serialization
     45 NS_IMPL_CI_INTERFACE_GETTER0(nsMozIconURI)
     46 
     47 nsMozIconURI::nsMozIconURI() : mSize(DEFAULT_IMAGE_SIZE) {}
     48 
     49 nsMozIconURI::~nsMozIconURI() = default;
     50 
     51 NS_IMPL_ADDREF(nsMozIconURI)
     52 NS_IMPL_RELEASE(nsMozIconURI)
     53 
     54 NS_INTERFACE_MAP_BEGIN(nsMozIconURI)
     55  if (aIID.Equals(kThisIconURIImplementationCID)) {
     56    foundInterface = static_cast<nsIURI*>(this);
     57  } else
     58    NS_INTERFACE_MAP_ENTRY(nsIMozIconURI)
     59  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURI)
     60  NS_INTERFACE_MAP_ENTRY(nsIURI)
     61  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsINestedURI, mIconURL)
     62  NS_INTERFACE_MAP_ENTRY(nsISerializable)
     63  NS_IMPL_QUERY_CLASSINFO(nsMozIconURI)
     64 NS_INTERFACE_MAP_END
     65 
     66 #define MOZICON_SCHEME "moz-icon:"
     67 #define MOZICON_SCHEME_LEN (sizeof(MOZICON_SCHEME) - 1)
     68 
     69 ////////////////////////////////////////////////////////////////////////////////
     70 // nsIURI methods:
     71 
     72 NS_IMETHODIMP
     73 nsMozIconURI::GetSpec(nsACString& aSpec) {
     74  aSpec = MOZICON_SCHEME;
     75 
     76  if (mIconURL) {
     77    nsAutoCString fileIconSpec;
     78    nsresult rv = mIconURL->GetSpec(fileIconSpec);
     79    NS_ENSURE_SUCCESS(rv, rv);
     80    aSpec += fileIconSpec;
     81  } else if (!mStockIcon.IsEmpty()) {
     82    aSpec += "//stock/";
     83    aSpec += mStockIcon;
     84  } else {
     85    aSpec += "//";
     86    aSpec += mFileName;
     87  }
     88 
     89  aSpec += "?size=";
     90  {
     91    char buf[20];
     92    SprintfLiteral(buf, "%d", mSize);
     93    aSpec.Append(buf);
     94  }
     95 
     96  if (!mContentType.IsEmpty()) {
     97    aSpec += "&contentType=";
     98    aSpec += mContentType.get();
     99  }
    100 
    101  if (mScale != 1) {
    102    aSpec += "&scale=";
    103    aSpec.AppendInt(mScale);
    104  }
    105 
    106  if (mDark) {
    107    aSpec += "&dark=";
    108    aSpec.AppendInt(*mDark ? 1 : 0);
    109  }
    110 
    111  return NS_OK;
    112 }
    113 
    114 NS_IMETHODIMP
    115 nsMozIconURI::GetSpecIgnoringRef(nsACString& result) { return GetSpec(result); }
    116 
    117 NS_IMETHODIMP
    118 nsMozIconURI::GetDisplaySpec(nsACString& aUnicodeSpec) {
    119  return GetSpec(aUnicodeSpec);
    120 }
    121 
    122 NS_IMETHODIMP
    123 nsMozIconURI::GetDisplayHostPort(nsACString& aUnicodeHostPort) {
    124  return GetHostPort(aUnicodeHostPort);
    125 }
    126 
    127 NS_IMETHODIMP
    128 nsMozIconURI::GetDisplayHost(nsACString& aUnicodeHost) {
    129  return GetHost(aUnicodeHost);
    130 }
    131 
    132 NS_IMETHODIMP
    133 nsMozIconURI::GetDisplayPrePath(nsACString& aPrePath) {
    134  return GetPrePath(aPrePath);
    135 }
    136 
    137 NS_IMETHODIMP
    138 nsMozIconURI::GetHasRef(bool* result) {
    139  *result = false;
    140  return NS_OK;
    141 }
    142 
    143 NS_IMETHODIMP
    144 nsMozIconURI::GetHasUserPass(bool* result) {
    145  *result = false;
    146  return NS_OK;
    147 }
    148 
    149 NS_IMETHODIMP
    150 nsMozIconURI::GetHasQuery(bool* result) {
    151  *result = false;
    152  return NS_OK;
    153 }
    154 
    155 NS_IMPL_NSIURIMUTATOR_ISUPPORTS(nsMozIconURI::Mutator, nsIURISetters,
    156                                nsIURIMutator, nsISerializable)
    157 
    158 NS_IMETHODIMP
    159 nsMozIconURI::Mutate(nsIURIMutator** aMutator) {
    160  RefPtr<nsMozIconURI::Mutator> mutator = new nsMozIconURI::Mutator();
    161  nsresult rv = mutator->InitFromURI(this);
    162  if (NS_FAILED(rv)) {
    163    return rv;
    164  }
    165  mutator.forget(aMutator);
    166  return NS_OK;
    167 }
    168 
    169 // helper function for parsing out attributes like size, and contentType
    170 // from the icon url.
    171 // takes a string like ?size=32&contentType=text/html and returns a new string
    172 // containing just the attribute value. i.e you could pass in this string with
    173 // an attribute name of 'size=', this will return 32
    174 // Assumption: attribute pairs in the string are separated by '&'.
    175 static void extractAttributeValue(const char* aSearchString,
    176                                  const char* aAttributeName,
    177                                  nsCString& aResult) {
    178  aResult.Truncate();
    179 
    180  if (aSearchString && aAttributeName) {
    181    // search the string for attributeName
    182    uint32_t attributeNameSize = strlen(aAttributeName);
    183    const char* startOfAttribute = PL_strcasestr(aSearchString, aAttributeName);
    184    if (startOfAttribute &&
    185        (*(startOfAttribute - 1) == '?' || *(startOfAttribute - 1) == '&')) {
    186      startOfAttribute += attributeNameSize;  // skip over the attributeName
    187      // is there something after the attribute name
    188      if (*startOfAttribute) {
    189        const char* endofAttribute = strchr(startOfAttribute, '&');
    190        if (endofAttribute) {
    191          aResult.Assign(Substring(startOfAttribute, endofAttribute));
    192        } else {
    193          aResult.Assign(startOfAttribute);
    194        }
    195      }  // if we have a attribute value
    196    }  // if we have a attribute name
    197  }  // if we got non-null search string and attribute name values
    198 }
    199 
    200 nsresult nsMozIconURI::SetSpecInternal(const nsACString& aSpec) {
    201  // Reset everything to default values.
    202  mIconURL = nullptr;
    203  mSize = DEFAULT_IMAGE_SIZE;
    204  mContentType.Truncate();
    205  mFileName.Truncate();
    206  mStockIcon.Truncate();
    207  mScale = 1;
    208  mDark.reset();
    209 
    210  nsAutoCString iconSpec(aSpec);
    211  if (!Substring(iconSpec, 0, MOZICON_SCHEME_LEN)
    212           .EqualsLiteral(MOZICON_SCHEME) ||
    213      (!Substring(iconSpec, MOZICON_SCHEME_LEN, 7).EqualsLiteral("file://") &&
    214       // Checking for the leading '//' will match both the '//stock/' and
    215       // '//.foo' cases:
    216       !Substring(iconSpec, MOZICON_SCHEME_LEN, 2).EqualsLiteral("//"))) {
    217    return NS_ERROR_MALFORMED_URI;
    218  }
    219 
    220  int32_t questionMarkPos = iconSpec.Find("?");
    221  if (questionMarkPos != -1 &&
    222      static_cast<int32_t>(iconSpec.Length()) > (questionMarkPos + 1)) {
    223    extractAttributeValue(iconSpec.get(), "contentType=", mContentType);
    224 
    225    nsAutoCString sizeString;
    226    extractAttributeValue(iconSpec.get(), "size=", sizeString);
    227    if (!sizeString.IsEmpty()) {
    228      int32_t sizeValue = atoi(sizeString.get());
    229      if (sizeValue > 0) {
    230        mSize = sizeValue;
    231      }
    232    }
    233 
    234    nsAutoCString scaleString;
    235    extractAttributeValue(iconSpec.get(), "scale=", scaleString);
    236    if (!scaleString.IsEmpty()) {
    237      int32_t scaleValue = atoi(scaleString.get());
    238      if (scaleValue > 0) {
    239        mScale = scaleValue;
    240      }
    241    }
    242 
    243    nsAutoCString darkString;
    244    extractAttributeValue(iconSpec.get(), "dark=", darkString);
    245    if (!darkString.IsEmpty()) {
    246      int32_t darkValue = atoi(darkString.get());
    247      mDark = Some(darkValue != 0);
    248    }
    249  }
    250 
    251  int32_t pathLength = iconSpec.Length() - MOZICON_SCHEME_LEN;
    252  if (questionMarkPos != -1) {
    253    pathLength = questionMarkPos - MOZICON_SCHEME_LEN;
    254  }
    255  if (pathLength < 3) {
    256    return NS_ERROR_MALFORMED_URI;
    257  }
    258 
    259  nsAutoCString iconPath(Substring(iconSpec, MOZICON_SCHEME_LEN, pathLength));
    260 
    261  // Icon URI path can have three forms:
    262  // (1) //stock/<icon-identifier>
    263  // (2) //<some dummy file with an extension>
    264  // (3) a valid URL
    265 
    266  if (!strncmp("//stock/", iconPath.get(), 8)) {
    267    mStockIcon.Assign(Substring(iconPath, 8));
    268    // An icon identifier must always be specified.
    269    if (mStockIcon.IsEmpty()) {
    270      return NS_ERROR_MALFORMED_URI;
    271    }
    272    return NS_OK;
    273  }
    274 
    275  if (StringBeginsWith(iconPath, "//"_ns)) {
    276    // Sanity check this supposed dummy file name.
    277    if (iconPath.Length() > SANE_FILE_NAME_LEN) {
    278      return NS_ERROR_MALFORMED_URI;
    279    }
    280    iconPath.Cut(0, 2);
    281    mFileName.Assign(iconPath);
    282  }
    283 
    284  nsresult rv;
    285  nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
    286  NS_ENSURE_SUCCESS(rv, rv);
    287 
    288  nsCOMPtr<nsIURI> uri;
    289  ioService->NewURI(iconPath, nullptr, nullptr, getter_AddRefs(uri));
    290  mIconURL = do_QueryInterface(uri);
    291  if (mIconURL) {
    292    // The inner URI should be a 'file:' one. If not, bail.
    293    if (!mIconURL->SchemeIs("file")) {
    294      return NS_ERROR_MALFORMED_URI;
    295    }
    296    mFileName.Truncate();
    297  } else if (mFileName.IsEmpty()) {
    298    return NS_ERROR_MALFORMED_URI;
    299  }
    300 
    301  return NS_OK;
    302 }
    303 
    304 NS_IMETHODIMP
    305 nsMozIconURI::GetPrePath(nsACString& prePath) {
    306  prePath = MOZICON_SCHEME;
    307  return NS_OK;
    308 }
    309 
    310 NS_IMETHODIMP
    311 nsMozIconURI::GetScheme(nsACString& aScheme) {
    312  aScheme = "moz-icon";
    313  return NS_OK;
    314 }
    315 
    316 nsresult nsMozIconURI::SetScheme(const nsACString& aScheme) {
    317  // doesn't make sense to set the scheme of a moz-icon URL
    318  return NS_ERROR_FAILURE;
    319 }
    320 
    321 NS_IMETHODIMP
    322 nsMozIconURI::GetUsername(nsACString& aUsername) { return NS_ERROR_FAILURE; }
    323 
    324 nsresult nsMozIconURI::SetUsername(const nsACString& aUsername) {
    325  return NS_ERROR_FAILURE;
    326 }
    327 
    328 NS_IMETHODIMP
    329 nsMozIconURI::GetPassword(nsACString& aPassword) { return NS_ERROR_FAILURE; }
    330 
    331 nsresult nsMozIconURI::SetPassword(const nsACString& aPassword) {
    332  return NS_ERROR_FAILURE;
    333 }
    334 
    335 NS_IMETHODIMP
    336 nsMozIconURI::GetUserPass(nsACString& aUserPass) { return NS_ERROR_FAILURE; }
    337 
    338 nsresult nsMozIconURI::SetUserPass(const nsACString& aUserPass) {
    339  return NS_ERROR_FAILURE;
    340 }
    341 
    342 NS_IMETHODIMP
    343 nsMozIconURI::GetHostPort(nsACString& aHostPort) { return NS_ERROR_FAILURE; }
    344 
    345 nsresult nsMozIconURI::SetHostPort(const nsACString& aHostPort) {
    346  return NS_ERROR_FAILURE;
    347 }
    348 
    349 NS_IMETHODIMP
    350 nsMozIconURI::GetHost(nsACString& aHost) { return NS_ERROR_FAILURE; }
    351 
    352 nsresult nsMozIconURI::SetHost(const nsACString& aHost) {
    353  return NS_ERROR_FAILURE;
    354 }
    355 
    356 NS_IMETHODIMP
    357 nsMozIconURI::GetPort(int32_t* aPort) { return NS_ERROR_FAILURE; }
    358 
    359 nsresult nsMozIconURI::SetPort(int32_t aPort) { return NS_ERROR_FAILURE; }
    360 
    361 NS_IMETHODIMP
    362 nsMozIconURI::GetPathQueryRef(nsACString& aPath) {
    363  aPath.Truncate();
    364  return NS_OK;
    365 }
    366 
    367 nsresult nsMozIconURI::SetPathQueryRef(const nsACString& aPath) {
    368  return NS_ERROR_FAILURE;
    369 }
    370 
    371 NS_IMETHODIMP
    372 nsMozIconURI::GetFilePath(nsACString& aFilePath) {
    373  aFilePath.Truncate();
    374  return NS_OK;
    375 }
    376 
    377 nsresult nsMozIconURI::SetFilePath(const nsACString& aFilePath) {
    378  return NS_ERROR_FAILURE;
    379 }
    380 
    381 NS_IMETHODIMP
    382 nsMozIconURI::GetQuery(nsACString& aQuery) {
    383  aQuery.Truncate();
    384  return NS_OK;
    385 }
    386 
    387 nsresult nsMozIconURI::SetQuery(const nsACString& aQuery) {
    388  return NS_ERROR_FAILURE;
    389 }
    390 
    391 nsresult nsMozIconURI::SetQueryWithEncoding(const nsACString& aQuery,
    392                                            const Encoding* aEncoding) {
    393  return NS_ERROR_FAILURE;
    394 }
    395 
    396 NS_IMETHODIMP
    397 nsMozIconURI::GetRef(nsACString& aRef) {
    398  aRef.Truncate();
    399  return NS_OK;
    400 }
    401 
    402 nsresult nsMozIconURI::SetRef(const nsACString& aRef) {
    403  return NS_ERROR_FAILURE;
    404 }
    405 
    406 NS_IMETHODIMP
    407 nsMozIconURI::Equals(nsIURI* other, bool* result) {
    408  *result = false;
    409  NS_ENSURE_ARG_POINTER(other);
    410  MOZ_ASSERT(result, "null pointer");
    411 
    412  nsAutoCString spec1;
    413  nsAutoCString spec2;
    414 
    415  nsresult rv = GetSpec(spec1);
    416  NS_ENSURE_SUCCESS(rv, rv);
    417  rv = other->GetSpec(spec2);
    418  NS_ENSURE_SUCCESS(rv, rv);
    419 
    420  if (!nsCRT::strcasecmp(spec1.get(), spec2.get())) {
    421    *result = true;
    422  } else {
    423    *result = false;
    424  }
    425  return NS_OK;
    426 }
    427 
    428 NS_IMETHODIMP
    429 nsMozIconURI::EqualsExceptRef(nsIURI* other, bool* result) {
    430  // GetRef/SetRef not supported by nsMozIconURI, so
    431  // EqualsExceptRef() is the same as Equals().
    432  return Equals(other, result);
    433 }
    434 
    435 NS_IMETHODIMP
    436 nsMozIconURI::SchemeIs(const char* aScheme, bool* aEquals) {
    437  MOZ_ASSERT(aEquals, "null pointer");
    438  if (!aScheme) {
    439    *aEquals = false;
    440    return NS_OK;
    441  }
    442 
    443  *aEquals = nsCRT::strcasecmp("moz-icon", aScheme) == 0;
    444  return NS_OK;
    445 }
    446 
    447 nsresult nsMozIconURI::Clone(nsIURI** result) {
    448  nsCOMPtr<nsIURL> newIconURL;
    449  if (mIconURL) {
    450    newIconURL = mIconURL;
    451  }
    452 
    453  RefPtr<nsMozIconURI> uri = new nsMozIconURI();
    454  newIconURL.swap(uri->mIconURL);
    455  uri->mSize = mSize;
    456  uri->mContentType = mContentType;
    457  uri->mFileName = mFileName;
    458  uri->mStockIcon = mStockIcon;
    459  uri.forget(result);
    460 
    461  return NS_OK;
    462 }
    463 
    464 NS_IMETHODIMP
    465 nsMozIconURI::Resolve(const nsACString& relativePath, nsACString& result) {
    466  return NS_ERROR_NOT_IMPLEMENTED;
    467 }
    468 
    469 NS_IMETHODIMP
    470 nsMozIconURI::GetAsciiSpec(nsACString& aSpecA) { return GetSpec(aSpecA); }
    471 
    472 NS_IMETHODIMP
    473 nsMozIconURI::GetAsciiHostPort(nsACString& aHostPortA) {
    474  return GetHostPort(aHostPortA);
    475 }
    476 
    477 NS_IMETHODIMP
    478 nsMozIconURI::GetAsciiHost(nsACString& aHostA) { return GetHost(aHostA); }
    479 
    480 ////////////////////////////////////////////////////////////////////////////////
    481 // nsIIconUri methods:
    482 
    483 NS_IMETHODIMP
    484 nsMozIconURI::GetIconURL(nsIURL** aFileUrl) {
    485  *aFileUrl = mIconURL;
    486  NS_IF_ADDREF(*aFileUrl);
    487  return NS_OK;
    488 }
    489 
    490 NS_IMETHODIMP
    491 nsMozIconURI::GetImageSize(uint32_t* aImageSize) {
    492  *aImageSize = mSize;
    493  return NS_OK;
    494 }
    495 
    496 NS_IMETHODIMP
    497 nsMozIconURI::GetImageScale(uint32_t* aImageScale) {
    498  *aImageScale = mScale;
    499  return NS_OK;
    500 }
    501 
    502 NS_IMETHODIMP
    503 nsMozIconURI::GetImageDark(bool* aImageDark) {
    504  if (!mDark) {
    505    return NS_ERROR_FAILURE;
    506  }
    507  *aImageDark = *mDark;
    508  return NS_OK;
    509 }
    510 
    511 NS_IMETHODIMP
    512 nsMozIconURI::GetContentType(nsACString& aContentType) {
    513  aContentType = mContentType;
    514  return NS_OK;
    515 }
    516 
    517 NS_IMETHODIMP
    518 nsMozIconURI::GetFileExtension(nsACString& aFileExtension) {
    519  // First, try to get the extension from mIconURL if we have one
    520  if (mIconURL) {
    521    nsAutoCString fileExt;
    522    if (NS_SUCCEEDED(mIconURL->GetFileExtension(fileExt))) {
    523      if (!fileExt.IsEmpty()) {
    524        // unfortunately, this code doesn't give us the required '.' in
    525        // front of the extension so we have to do it ourselves.
    526        aFileExtension.Assign('.');
    527        aFileExtension.Append(fileExt);
    528      }
    529    }
    530    return NS_OK;
    531  }
    532 
    533  if (!mFileName.IsEmpty()) {
    534    // truncate the extension out of the file path...
    535    const char* chFileName = mFileName.get();  // get the underlying buffer
    536    const char* fileExt = strrchr(chFileName, '.');
    537    if (!fileExt) {
    538      return NS_OK;
    539    }
    540    aFileExtension = fileExt;
    541  }
    542 
    543  return NS_OK;
    544 }
    545 
    546 NS_IMETHODIMP
    547 nsMozIconURI::GetStockIcon(nsACString& aStockIcon) {
    548  aStockIcon = mStockIcon;
    549  return NS_OK;
    550 }
    551 
    552 void nsMozIconURI::Serialize(URIParams& aParams) {
    553  IconURIParams params;
    554 
    555  if (mIconURL) {
    556    URIParams iconURLParams;
    557    SerializeURI(mIconURL, iconURLParams);
    558    if (iconURLParams.type() == URIParams::T__None) {
    559      // Serialization failed, bail.
    560      return;
    561    }
    562 
    563    params.uri() = Some(std::move(iconURLParams));
    564  } else {
    565    params.uri() = Nothing();
    566  }
    567 
    568  params.size() = mSize;
    569  params.contentType() = mContentType;
    570  params.fileName() = mFileName;
    571  params.stockIcon() = mStockIcon;
    572 
    573  params.iconScale() = mScale;
    574  params.iconDark() = mDark;
    575 
    576  aParams = params;
    577 }
    578 
    579 bool nsMozIconURI::Deserialize(const URIParams& aParams) {
    580  if (aParams.type() != URIParams::TIconURIParams) {
    581    MOZ_ASSERT_UNREACHABLE("Received unknown URI from other process!");
    582    return false;
    583  }
    584 
    585  const IconURIParams& params = aParams.get_IconURIParams();
    586  if (params.uri().isSome()) {
    587    nsCOMPtr<nsIURI> uri = DeserializeURI(params.uri().ref());
    588    mIconURL = do_QueryInterface(uri);
    589    if (!mIconURL) {
    590      MOZ_ASSERT_UNREACHABLE("bad nsIURI passed");
    591      return false;
    592    }
    593  }
    594 
    595  mSize = params.size();
    596  mContentType = params.contentType();
    597  mFileName = params.fileName();
    598  mStockIcon = params.stockIcon();
    599 
    600  mScale = params.iconScale();
    601  mDark = params.iconDark();
    602 
    603  return true;
    604 }
    605 
    606 size_t nsMozIconURI::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) {
    607  // We don't need to calculate this unless it shows up in DMD.
    608  return 0;
    609 };
    610 
    611 NS_IMETHODIMP
    612 nsMozIconURI::GetInnerURI(nsIURI** aURI) {
    613  nsCOMPtr<nsIURI> iconURL = mIconURL;
    614  if (!iconURL) {
    615    *aURI = nullptr;
    616    return NS_ERROR_FAILURE;
    617  }
    618 
    619  iconURL.forget(aURI);
    620  return NS_OK;
    621 }
    622 
    623 NS_IMETHODIMP
    624 nsMozIconURI::GetInnermostURI(nsIURI** aURI) {
    625  return NS_ImplGetInnermostURI(this, aURI);
    626 }
    627 
    628 NS_IMETHODIMP
    629 nsMozIconURI::Read(nsIObjectInputStream* aStream) {
    630  MOZ_ASSERT_UNREACHABLE("Use nsIURIMutator.read() instead");
    631  return NS_ERROR_NOT_IMPLEMENTED;
    632 }
    633 
    634 nsresult nsMozIconURI::ReadPrivate(nsIObjectInputStream* aStream) {
    635  nsAutoCString spec;
    636  nsresult rv = aStream->ReadCString(spec);
    637  NS_ENSURE_SUCCESS(rv, rv);
    638  return SetSpecInternal(spec);
    639 }
    640 
    641 NS_IMETHODIMP
    642 nsMozIconURI::Write(nsIObjectOutputStream* aStream) {
    643  nsAutoCString spec;
    644  nsresult rv = GetSpec(spec);
    645  NS_ENSURE_SUCCESS(rv, rv);
    646  return aStream->WriteStringZ(spec.get());
    647 }