xpcom/io/nsScriptableInputStream.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 "nsScriptableInputStream.h"
     7 #include "nsMemory.h"
     8 #include "nsString.h"
    10 NS_IMPL_ISUPPORTS(nsScriptableInputStream, nsIScriptableInputStream)
    12 // nsIScriptableInputStream methods
    13 NS_IMETHODIMP
    14 nsScriptableInputStream::Close(void) {
    15     if (!mInputStream) return NS_ERROR_NOT_INITIALIZED;
    16     return mInputStream->Close();
    17 }
    19 NS_IMETHODIMP
    20 nsScriptableInputStream::Init(nsIInputStream *aInputStream) {
    21     if (!aInputStream) return NS_ERROR_NULL_POINTER;
    22     mInputStream = aInputStream;
    23     return NS_OK;
    24 }
    26 NS_IMETHODIMP
    27 nsScriptableInputStream::Available(uint64_t *_retval) {
    28     if (!mInputStream) return NS_ERROR_NOT_INITIALIZED;
    29     return mInputStream->Available(_retval);
    30 }
    32 NS_IMETHODIMP
    33 nsScriptableInputStream::Read(uint32_t aCount, char **_retval) {
    34     nsresult rv = NS_OK;
    35     uint64_t count64 = 0;
    36     char *buffer = nullptr;
    38     if (!mInputStream) return NS_ERROR_NOT_INITIALIZED;
    40     rv = mInputStream->Available(&count64);
    41     if (NS_FAILED(rv)) return rv;
    43     // bug716556 - Ensure count+1 doesn't overflow
    44     uint32_t count = XPCOM_MIN((uint32_t)XPCOM_MIN<uint64_t>(count64, aCount), UINT32_MAX - 1);
    45     buffer = (char*)moz_malloc(count+1); // make room for '\0'
    46     if (!buffer) return NS_ERROR_OUT_OF_MEMORY;
    48     rv = ReadHelper(buffer, count);
    49     if (NS_FAILED(rv)) {
    50         nsMemory::Free(buffer);
    51         return rv;
    52     }
    54     buffer[count] = '\0';
    55     *_retval = buffer;
    56     return NS_OK;
    57 }
    59 NS_IMETHODIMP
    60 nsScriptableInputStream::ReadBytes(uint32_t aCount, nsACString &_retval) {
    61     if (!mInputStream) {
    62       return NS_ERROR_NOT_INITIALIZED;
    63     }
    65     _retval.SetLength(aCount);
    66     if (_retval.Length() != aCount) {
    67       return NS_ERROR_OUT_OF_MEMORY;
    68     }
    70     char *ptr = _retval.BeginWriting();
    71     nsresult rv = ReadHelper(ptr, aCount);
    72     if (NS_FAILED(rv)) {
    73       _retval.Truncate();
    74     }
    75     return rv;
    76 }
    78 nsresult
    79 nsScriptableInputStream::ReadHelper(char* aBuffer, uint32_t aCount)
    80 {
    81     uint32_t totalBytesRead = 0;
    82     while (1) {
    83       uint32_t bytesRead;
    84       nsresult rv = mInputStream->Read(aBuffer + totalBytesRead,
    85                                        aCount - totalBytesRead,
    86                                        &bytesRead);
    87       if (NS_FAILED(rv)) {
    88         return rv;
    89       }
    91       totalBytesRead += bytesRead;
    92       if (totalBytesRead == aCount) {
    93         break;
    94       }
    96       // If we have read zero bytes, we have hit EOF.
    97       if (bytesRead == 0) {
    98         return NS_ERROR_FAILURE;
    99       }
   101     }
   102     return NS_OK;
   103 }
   105 nsresult
   106 nsScriptableInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) {
   107     if (aOuter) return NS_ERROR_NO_AGGREGATION;
   109     nsScriptableInputStream *sis = new nsScriptableInputStream();
   110     if (!sis) return NS_ERROR_OUT_OF_MEMORY;
   112     NS_ADDREF(sis);
   113     nsresult rv = sis->QueryInterface(aIID, aResult);
   114     NS_RELEASE(sis);
   115     return rv;
   116 }

mercurial