xpcom/glue/nsEnumeratorUtils.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 4; 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/Attributes.h"
     8 #include "nsEnumeratorUtils.h"
    10 #include "nsISimpleEnumerator.h"
    11 #include "nsIStringEnumerator.h"
    13 #include "nsCOMPtr.h"
    15 class EmptyEnumeratorImpl : public nsISimpleEnumerator,
    16                             public nsIUTF8StringEnumerator,
    17                             public nsIStringEnumerator
    18 {
    19 public:
    20     EmptyEnumeratorImpl() {}
    21     // nsISupports interface
    22     NS_DECL_ISUPPORTS_INHERITED  // not really inherited, but no mRefCnt
    24     // nsISimpleEnumerator
    25     NS_DECL_NSISIMPLEENUMERATOR
    26     NS_DECL_NSIUTF8STRINGENUMERATOR
    27     // can't use NS_DECL_NSISTRINGENUMERATOR because they share the
    28     // HasMore() signature
    29     NS_IMETHOD GetNext(nsAString& aResult);
    31     static EmptyEnumeratorImpl* GetInstance() {
    32       static const EmptyEnumeratorImpl kInstance;
    33       return const_cast<EmptyEnumeratorImpl*>(&kInstance);
    34     }
    35 };
    37 // nsISupports interface
    38 NS_IMETHODIMP_(MozExternalRefCountType) EmptyEnumeratorImpl::AddRef(void)
    39 {
    40     return 2;
    41 }
    43 NS_IMETHODIMP_(MozExternalRefCountType) EmptyEnumeratorImpl::Release(void)
    44 {
    45     return 1;
    46 }
    48 NS_IMPL_QUERY_INTERFACE(EmptyEnumeratorImpl, nsISimpleEnumerator,
    49                         nsIUTF8StringEnumerator, nsIStringEnumerator)
    51 // nsISimpleEnumerator interface
    52 NS_IMETHODIMP EmptyEnumeratorImpl::HasMoreElements(bool* aResult)
    53 {
    54     *aResult = false;
    55     return NS_OK;
    56 }
    58 NS_IMETHODIMP EmptyEnumeratorImpl::HasMore(bool* aResult)
    59 {
    60     *aResult = false;
    61     return NS_OK;
    62 }
    64 NS_IMETHODIMP EmptyEnumeratorImpl::GetNext(nsISupports** aResult)
    65 {
    66     return NS_ERROR_UNEXPECTED;
    67 }
    69 NS_IMETHODIMP EmptyEnumeratorImpl::GetNext(nsACString& aResult)
    70 {
    71     return NS_ERROR_UNEXPECTED;
    72 }
    74 NS_IMETHODIMP EmptyEnumeratorImpl::GetNext(nsAString& aResult)
    75 {
    76     return NS_ERROR_UNEXPECTED;
    77 }
    79 nsresult
    80 NS_NewEmptyEnumerator(nsISimpleEnumerator** aResult)
    81 {
    82     *aResult = EmptyEnumeratorImpl::GetInstance();
    83     return NS_OK;
    84 }
    86 ////////////////////////////////////////////////////////////////////////////////
    88 class nsSingletonEnumerator MOZ_FINAL : public nsISimpleEnumerator
    89 {
    90 public:
    91     NS_DECL_ISUPPORTS
    93     // nsISimpleEnumerator methods
    94     NS_IMETHOD HasMoreElements(bool* aResult);
    95     NS_IMETHOD GetNext(nsISupports** aResult);
    97     nsSingletonEnumerator(nsISupports* aValue);
    99 private:
   100     ~nsSingletonEnumerator();
   102 protected:
   103     nsISupports* mValue;
   104     bool mConsumed;
   105 };
   107 nsSingletonEnumerator::nsSingletonEnumerator(nsISupports* aValue)
   108     : mValue(aValue)
   109 {
   110     NS_IF_ADDREF(mValue);
   111     mConsumed = (mValue ? false : true);
   112 }
   114 nsSingletonEnumerator::~nsSingletonEnumerator()
   115 {
   116     NS_IF_RELEASE(mValue);
   117 }
   119 NS_IMPL_ISUPPORTS(nsSingletonEnumerator, nsISimpleEnumerator)
   121 NS_IMETHODIMP
   122 nsSingletonEnumerator::HasMoreElements(bool* aResult)
   123 {
   124     NS_PRECONDITION(aResult != 0, "null ptr");
   125     if (! aResult)
   126         return NS_ERROR_NULL_POINTER;
   128     *aResult = !mConsumed;
   129     return NS_OK;
   130 }
   133 NS_IMETHODIMP
   134 nsSingletonEnumerator::GetNext(nsISupports** aResult)
   135 {
   136     NS_PRECONDITION(aResult != 0, "null ptr");
   137     if (! aResult)
   138         return NS_ERROR_NULL_POINTER;
   140     if (mConsumed)
   141         return NS_ERROR_UNEXPECTED;
   143     mConsumed = true;
   145     *aResult = mValue;
   146     NS_ADDREF(*aResult);
   147     return NS_OK;
   148 }
   150 nsresult
   151 NS_NewSingletonEnumerator(nsISimpleEnumerator* *result,
   152                           nsISupports* singleton)
   153 {
   154     nsSingletonEnumerator* enumer = new nsSingletonEnumerator(singleton);
   155     if (enumer == nullptr)
   156         return NS_ERROR_OUT_OF_MEMORY;
   157     *result = enumer; 
   158     NS_ADDREF(*result);
   159     return NS_OK;
   160 }
   162 ////////////////////////////////////////////////////////////////////////////////
   164 class nsUnionEnumerator MOZ_FINAL : public nsISimpleEnumerator
   165 {
   166 public:
   167     NS_DECL_ISUPPORTS
   169     // nsISimpleEnumerator methods
   170     NS_IMETHOD HasMoreElements(bool* aResult);
   171     NS_IMETHOD GetNext(nsISupports** aResult);
   173     nsUnionEnumerator(nsISimpleEnumerator* firstEnumerator,
   174                       nsISimpleEnumerator* secondEnumerator);
   176 private:
   177     ~nsUnionEnumerator();
   179 protected:
   180     nsCOMPtr<nsISimpleEnumerator> mFirstEnumerator, mSecondEnumerator;
   181     bool mConsumed;
   182     bool mAtSecond;
   183 };
   185 nsUnionEnumerator::nsUnionEnumerator(nsISimpleEnumerator* firstEnumerator,
   186                                      nsISimpleEnumerator* secondEnumerator)
   187     : mFirstEnumerator(firstEnumerator),
   188       mSecondEnumerator(secondEnumerator),
   189       mConsumed(false), mAtSecond(false)
   190 {
   191 }
   193 nsUnionEnumerator::~nsUnionEnumerator()
   194 {
   195 }
   197 NS_IMPL_ISUPPORTS(nsUnionEnumerator, nsISimpleEnumerator)
   199 NS_IMETHODIMP
   200 nsUnionEnumerator::HasMoreElements(bool* aResult)
   201 {
   202     NS_PRECONDITION(aResult != 0, "null ptr");
   203     if (! aResult)
   204         return NS_ERROR_NULL_POINTER;
   206     nsresult rv;
   208     if (mConsumed) {
   209         *aResult = false;
   210         return NS_OK;
   211     }
   213     if (! mAtSecond) {
   214         rv = mFirstEnumerator->HasMoreElements(aResult);
   215         if (NS_FAILED(rv)) return rv;
   217         if (*aResult)
   218             return NS_OK;
   220         mAtSecond = true;
   221     }
   223     rv = mSecondEnumerator->HasMoreElements(aResult);
   224     if (NS_FAILED(rv)) return rv;
   226     if (*aResult)
   227         return NS_OK;
   229     *aResult = false;
   230     mConsumed = true;
   231     return NS_OK;
   232 }
   234 NS_IMETHODIMP
   235 nsUnionEnumerator::GetNext(nsISupports** aResult)
   236 {
   237     NS_PRECONDITION(aResult != 0, "null ptr");
   238     if (! aResult)
   239         return NS_ERROR_NULL_POINTER;
   241     if (mConsumed)
   242         return NS_ERROR_UNEXPECTED;
   244     if (! mAtSecond)
   245         return mFirstEnumerator->GetNext(aResult);
   247     return mSecondEnumerator->GetNext(aResult);
   248 }
   250 nsresult
   251 NS_NewUnionEnumerator(nsISimpleEnumerator* *result,
   252                       nsISimpleEnumerator* firstEnumerator,
   253                       nsISimpleEnumerator* secondEnumerator)
   254 {
   255     *result = nullptr;
   256     if (! firstEnumerator) {
   257         *result = secondEnumerator;
   258     } else if (! secondEnumerator) {
   259         *result = firstEnumerator;
   260     } else {
   261         nsUnionEnumerator* enumer = new nsUnionEnumerator(firstEnumerator, secondEnumerator);
   262         if (enumer == nullptr)
   263             return NS_ERROR_OUT_OF_MEMORY;
   264         *result = enumer; 
   265     }
   266     NS_ADDREF(*result);
   267     return NS_OK;
   268 }

mercurial