Bug 215450: Allow uploading of files greater than 2gb in size. Involves making input streams 64-bit capable. Significant work done by Makoto Kato, finished by Honza Bambas. r=hbambas,bsmedberg,jdrew,sicking
authorHonza Bambas <honzab.moz@firemni.cz>
Fri, 10 Aug 2012 22:44:11 -0400
changeset 102168 14e988e17b792ef5f50feb9aa96dbf9d71052215
parent 102167 7f3d9cf9b3a1d17d6c0de62450408466fd7123f4
child 102169 1022af7974c986510eeaae7de4c85cb220fd7687
push id1001
push userttaubert@mozilla.com
push dateTue, 14 Aug 2012 04:19:19 +0000
treeherderfx-team@22288130fea2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershbambas, bsmedberg, jdrew, sicking
bugs215450
milestone17.0a1
Bug 215450: Allow uploading of files greater than 2gb in size. Involves making input streams 64-bit capable. Significant work done by Makoto Kato, finished by Honza Bambas. r=hbambas,bsmedberg,jdrew,sicking
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsSyncLoadService.cpp
content/base/src/nsXMLHttpRequest.cpp
content/html/content/src/nsHTMLCanvasElement.cpp
content/media/MediaResource.cpp
content/xul/document/src/nsXULPrototypeCache.cpp
dom/base/nsJSEnvironment.cpp
dom/devicestorage/nsDeviceStorage.cpp
dom/file/ArchiveZipFile.cpp
dom/file/FileStreamWrappers.cpp
dom/indexedDB/FileStream.cpp
dom/indexedDB/FileStream.h
dom/ipc/Blob.cpp
dom/src/json/nsJSON.cpp
extensions/gio/nsGIOProtocolHandler.cpp
extensions/gnomevfs/nsGnomeVFSProtocolHandler.cpp
extensions/pref/autoconfig/src/nsReadConfig.cpp
gfx/thebes/gfxASurface.cpp
image/encoders/bmp/nsBMPEncoder.cpp
image/encoders/ico/nsICOEncoder.cpp
image/encoders/jpeg/nsJPEGEncoder.cpp
image/encoders/png/nsPNGEncoder.cpp
image/src/imgTools.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
layout/base/nsPresShell.cpp
layout/style/nsFontFaceLoader.cpp
modules/libjar/nsJAR.cpp
modules/libjar/nsJARChannel.cpp
modules/libjar/nsJARInputStream.cpp
modules/libpref/src/Preferences.cpp
netwerk/base/public/nsNetUtil.h
netwerk/base/src/nsBaseContentStream.cpp
netwerk/base/src/nsBufferedStreams.cpp
netwerk/base/src/nsDirectoryIndexStream.cpp
netwerk/base/src/nsFileStreams.cpp
netwerk/base/src/nsFileStreams.h
netwerk/base/src/nsInputStreamChannel.cpp
netwerk/base/src/nsInputStreamPump.cpp
netwerk/base/src/nsMIMEInputStream.cpp
netwerk/base/src/nsPreloadedStream.cpp
netwerk/base/src/nsSocketTransport2.cpp
netwerk/base/src/nsStreamTransportService.cpp
netwerk/base/src/nsSyncStreamListener.cpp
netwerk/cache/nsCacheEntryDescriptor.cpp
netwerk/cache/nsDiskCacheStreams.cpp
netwerk/ipc/NeckoMessageUtils.h
netwerk/protocol/device/AndroidCaptureProvider.cpp
netwerk/protocol/device/GonkCaptureProvider.cpp
netwerk/protocol/file/nsFileChannel.cpp
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
netwerk/protocol/ftp/nsFtpConnectionThread.h
netwerk/protocol/ftp/nsFtpControlConnection.cpp
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/NullHttpTransaction.cpp
netwerk/protocol/http/SpdySession2.cpp
netwerk/protocol/http/SpdySession3.cpp
netwerk/protocol/http/nsAHttpTransaction.h
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpPipeline.cpp
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
netwerk/protocol/websocket/WebSocketChannel.cpp
netwerk/streamconv/converters/nsFTPDirListingConv.cpp
netwerk/streamconv/test/Converters.cpp
netwerk/streamconv/test/TestStreamConv.cpp
parser/xml/src/nsSAXXMLReader.cpp
rdf/base/src/nsRDFXMLDataSource.cpp
security/manager/ssl/src/nsNSSComponent.cpp
startupcache/StartupCacheUtils.cpp
toolkit/components/places/nsFaviconService.cpp
widget/windows/WinUtils.cpp
xpcom/io/Base64.cpp
xpcom/io/nsBinaryStream.cpp
xpcom/io/nsIInputStream.idl
xpcom/io/nsIScriptableInputStream.idl
xpcom/io/nsInputStreamTee.cpp
xpcom/io/nsMultiplexInputStream.cpp
xpcom/io/nsPipe3.cpp
xpcom/io/nsScriptableInputStream.cpp
xpcom/io/nsStorageStream.cpp
xpcom/io/nsStreamUtils.cpp
xpcom/io/nsStringStream.cpp
xpcom/tests/TestBase64.cpp
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -803,19 +803,23 @@ nsFrameScriptExecutor::LoadFrameScriptIn
   NS_NewChannel(getter_AddRefs(channel), uri);
   if (!channel) {
     return;
   }
 
   nsCOMPtr<nsIInputStream> input;
   channel->Open(getter_AddRefs(input));
   nsString dataString;
-  PRUint32 avail = 0;
-  if (input && NS_SUCCEEDED(input->Available(&avail)) && avail) {
+  PRUint64 avail64 = 0;
+  if (input && NS_SUCCEEDED(input->Available(&avail64)) && avail64) {
+    if (avail64 > PR_UINT32_MAX) {
+      return;
+    }
     nsCString buffer;
+    PRUint32 avail = (PRUint32)NS_MIN(avail64, (PRUint64)PR_UINT32_MAX);
     if (NS_FAILED(NS_ReadInputStreamToString(input, buffer, avail))) {
       return;
     }
     nsScriptLoader::ConvertToUTF16(channel, (PRUint8*)buffer.get(), avail,
                                    EmptyString(), nullptr, dataString);
   }
 
   if (!dataString.IsEmpty()) {
--- a/content/base/src/nsSyncLoadService.cpp
+++ b/content/base/src/nsSyncLoadService.cpp
@@ -347,30 +347,34 @@ nsSyncLoadService::PushSyncStreamToListe
         NS_ENSURE_SUCCESS(rv, rv);
 
         aIn = bufferedStream;
     }
 
     // Load
     rv = aListener->OnStartRequest(aChannel, nullptr);
     if (NS_SUCCEEDED(rv)) {
-        PRUint32 sourceOffset = 0;
+        PRUint64 sourceOffset = 0;
         while (1) {
-            PRUint32 readCount = 0;
+            PRUint64 readCount = 0;
             rv = aIn->Available(&readCount);
             if (NS_FAILED(rv) || !readCount) {
                 if (rv == NS_BASE_STREAM_CLOSED) {
                     // End of file, but not an error
                     rv = NS_OK;
                 }
                 break;
             }
 
+            if (readCount > PR_UINT32_MAX)
+                readCount = PR_UINT32_MAX;
+
             rv = aListener->OnDataAvailable(aChannel, nullptr, aIn,
-                                            sourceOffset, readCount);
+                                            (PRUint32)NS_MIN(sourceOffset, (PRUint64)PR_UINT32_MAX),
+                                            (PRUint32)readCount);
             if (NS_FAILED(rv)) {
                 break;
             }
             sourceOffset += readCount;
         }
     }
     if (NS_FAILED(rv)) {
         aChannel->Cancel(rv);
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2957,17 +2957,17 @@ nsXMLHttpRequest::Send(nsIVariant* aVari
                                        postDataStream, 
                                        4096);
         NS_ENSURE_SUCCESS(rv, rv);
 
         postDataStream = bufferedStream;
       }
 
       mUploadComplete = false;
-      PRUint32 uploadTotal = 0;
+      PRUint64 uploadTotal = 0;
       postDataStream->Available(&uploadTotal);
       mUploadTotal = uploadTotal;
 
       // We want to use a newer version of the upload channel that won't
       // ignore the necessary headers for an empty Content-Type.
       nsCOMPtr<nsIUploadChannel2> uploadChannel2(do_QueryInterface(httpChannel));
       // This assertion will fire if buggy extensions are installed
       NS_ASSERTION(uploadChannel2, "http must support nsIUploadChannel2");
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -354,21 +354,22 @@ nsHTMLCanvasElement::ToDataURLImpl(const
 
   // build data URL string
   if (fallbackToPNG)
     aDataURL = NS_LITERAL_STRING("data:image/png;base64,");
   else
     aDataURL = NS_LITERAL_STRING("data:") + type +
       NS_LITERAL_STRING(";base64,");
 
-  PRUint32 count;
+  PRUint64 count;
   rv = stream->Available(&count);
   NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(count <= PR_UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
 
-  return Base64EncodeInputStream(stream, aDataURL, count, aDataURL.Length());
+  return Base64EncodeInputStream(stream, aDataURL, (PRUint32)count, aDataURL.Length());
 }
 
 NS_IMETHODIMP
 nsHTMLCanvasElement::MozGetAsFile(const nsAString& aName,
                                   const nsAString& aType,
                                   PRUint8 optional_argc,
                                   nsIDOMFile** aResult)
 {
@@ -393,27 +394,28 @@ nsHTMLCanvasElement::MozGetAsFileImpl(co
                             fallbackToPNG);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString type(aType);
   if (fallbackToPNG) {
     type.AssignLiteral("image/png");
   }
 
-  PRUint32 imgSize;
+  PRUint64 imgSize;
   rv = stream->Available(&imgSize);
   NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(imgSize <= PR_UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
 
   void* imgData = nullptr;
-  rv = NS_ReadInputStreamToBuffer(stream, &imgData, imgSize);
+  rv = NS_ReadInputStreamToBuffer(stream, &imgData, (PRUint32)imgSize);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // The DOMFile takes ownership of the buffer
   nsRefPtr<nsDOMMemoryFile> file =
-    new nsDOMMemoryFile(imgData, imgSize, aName, type);
+    new nsDOMMemoryFile(imgData, (PRUint32)imgSize, aName, type);
 
   file.forget(aResult);
   return NS_OK;
 }
 
 nsresult
 nsHTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
                                       bool aForceThebes,
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -1048,23 +1048,23 @@ nsresult FileMediaResource::Open(nsIStre
   if (!mSeekable) {
     // XXX The file may just be a .url or similar
     // shortcut that points to a Web site. We need to fix this by
     // doing an async open and waiting until we locate the real resource,
     // then using that (if it's still a file!).
     return NS_ERROR_FAILURE;
   }
 
-  // Get the file size and inform the decoder. Only files up to 4GB are
-  // supported here.
-  PRUint32 size;
+  // Get the file size and inform the decoder.
+  PRUint64 size;
   rv = mInput->Available(&size);
-  if (NS_SUCCEEDED(rv)) {
-    mSize = size;
-  }
+  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(size <= PR_INT64_MAX, NS_ERROR_FILE_TOO_BIG);
+ 
+  mSize = (PRInt64)size;
 
   nsCOMPtr<nsIRunnable> event = new LoadedEvent(mDecoder);
   NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
   return NS_OK;
 }
 
 nsresult FileMediaResource::Close()
 {
--- a/content/xul/document/src/nsXULPrototypeCache.cpp
+++ b/content/xul/document/src/nsXULPrototypeCache.cpp
@@ -641,18 +641,27 @@ nsXULPrototypeCache::BeginCaching(nsIURI
             if (NS_FAILED(tmp)) {
               rv = tmp;
             }
             tmp = storageStream->NewInputStream(0, getter_AddRefs(inputStream));
             if (NS_FAILED(tmp)) {
               rv = tmp;
             }
         }
-        if (NS_SUCCEEDED(rv))
-            rv = inputStream->Available(&len);
+
+        if (NS_SUCCEEDED(rv)) {
+            PRUint64 len64;
+            rv = inputStream->Available(&len64);
+            if (NS_SUCCEEDED(rv)) {
+              if (len64 <= PR_UINT32_MAX)
+                len = (PRUint32)len64;
+              else
+                rv = NS_ERROR_FILE_TOO_BIG;
+            }
+        }
         
         if (NS_SUCCEEDED(rv)) {
             buf = new char[len];
             rv = inputStream->Read(buf, len, &amtRead);
             if (NS_SUCCEEDED(rv) && len == amtRead)
                 rv = startupCache->PutBuffer(kXULCacheInfoKey, buf, len);
             else {
                 rv = NS_ERROR_UNEXPECTED;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -3892,21 +3892,23 @@ ReadSourceFromFilename(JSContext *cx, co
   NS_ENSURE_SUCCESS(rv, rv);
   if (!scheme.EqualsLiteral("file") && !scheme.EqualsLiteral("jar"))
     return NS_OK;
 
   nsCOMPtr<nsIInputStream> scriptStream;
   rv = scriptChannel->Open(getter_AddRefs(scriptStream));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRUint32 rawLen;
+  PRUint64 rawLen;
   rv = scriptStream->Available(&rawLen);
   NS_ENSURE_SUCCESS(rv, rv);
   if (!rawLen)
     return NS_ERROR_FAILURE;
+  if (rawLen > PR_UINT32_MAX)
+    return NS_ERROR_FILE_TOO_BIG;
 
   // Allocate an internal buf the size of the file.
   nsAutoArrayPtr<unsigned char> buf(new unsigned char[rawLen]);
   if (!buf)
     return NS_ERROR_OUT_OF_MEMORY;
 
   unsigned char *ptr = buf, *end = ptr + rawLen;
   while (ptr < end) {
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -153,17 +153,17 @@ DeviceStorageFile::Write(nsIInputStream*
     return NS_ERROR_FAILURE;
   }
 
   nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  PRUint32 bufSize;
+  PRUint64 bufSize = 0;
   aInputStream->Available(&bufSize);
 
   nsCOMPtr<nsIOutputStream> outputStream;
   NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mFile);
 
   if (!outputStream) {
     return NS_ERROR_FAILURE;
   }
@@ -172,22 +172,30 @@ DeviceStorageFile::Write(nsIInputStream*
   NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
                              outputStream,
                              4096*4);
 
   if (!bufferedOutputStream) {
     return NS_ERROR_FAILURE;
   }
 
-  PRUint32 wrote;
-  bufferedOutputStream->WriteFrom(aInputStream, bufSize, &wrote);
+  rv = NS_OK;
+  while (bufSize) {
+    PRUint32 wrote;
+    rv = bufferedOutputStream->WriteFrom(aInputStream, static_cast<PRUint32>(NS_MIN<PRUint64>(bufSize, PR_UINT32_MAX)), &wrote);
+    if (NS_FAILED(rv)) {
+      break;
+    }
+    bufSize -= wrote;
+  }
+
   bufferedOutputStream->Close();
   outputStream->Close();
-  if (bufSize != wrote) {
-    return NS_ERROR_FAILURE;
+  if (NS_FAILED(rv)) {
+    return rv;
   }
   return NS_OK;
 }
 
 nsresult
 DeviceStorageFile::Write(InfallibleTArray<PRUint8>& aBits) {
 
   nsresult rv = mFile->Create(nsIFile::NORMAL_FILE_TYPE, 00600);
--- a/dom/file/ArchiveZipFile.cpp
+++ b/dom/file/ArchiveZipFile.cpp
@@ -164,17 +164,17 @@ ArchiveInputStream::Close()
     inflateEnd(&mZs);
     mStatus = NotStarted;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-ArchiveInputStream::Available(PRUint32* _retval)
+ArchiveInputStream::Available(PRUint64* _retval)
 {
   *_retval = mLength - mZs.total_out - mStart;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ArchiveInputStream::Read(char* aBuffer,
                          PRUint32 aCount,
--- a/dom/file/FileStreamWrappers.cpp
+++ b/dom/file/FileStreamWrappers.cpp
@@ -134,17 +134,17 @@ FileInputStreamWrapper::Close()
 
   mOffset = 0;
   mLimit = 0;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FileInputStreamWrapper::Available(PRUint32* _retval)
+FileInputStreamWrapper::Available(PRUint64* _retval)
 {
   // Performing sync IO on the main thread is generally not allowed.
   // However, the input stream wrapper is also used to track reads performed by
   // other APIs like FileReader, XHR, etc.
   // In that case nsInputStreamChannel::OpenContentStream() calls Available()
   // before setting the content length property. This property is not important
   // to perform reads properly, so we can just return NS_BASE_STREAM_CLOSED
   // here. It causes OpenContentStream() to set the content length property to
--- a/dom/indexedDB/FileStream.cpp
+++ b/dom/indexedDB/FileStream.cpp
@@ -109,17 +109,17 @@ FileStream::Close()
 
     NS_ENSURE_TRUE(rc == 0, NS_BASE_STREAM_OSERROR);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FileStream::Available(PRUint32* aResult)
+FileStream::Available(PRUint64* aResult)
 {
   nsresult rv = DoPendingOpen();
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!mQuotaFile) {
     return NS_BASE_STREAM_CLOSED;
   }
 
--- a/dom/indexedDB/FileStream.h
+++ b/dom/indexedDB/FileStream.h
@@ -43,17 +43,17 @@ public:
   NS_DECL_NSISTANDARDFILESTREAM
   NS_DECL_NSIFILEMETADATA
 
   // nsIInputStream
   NS_IMETHOD
   Close();
 
   NS_IMETHOD
-  Available(PRUint32* _retval);
+  Available(PRUint64* _retval);
 
   NS_IMETHOD
   Read(char* aBuf, PRUint32 aCount, PRUint32* _retval);
 
   NS_IMETHOD
   ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, PRUint32 aCount,
                PRUint32* _retval);
 
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -79,17 +79,17 @@ public:
 
     rv = mStream->Close();
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
   }
 
   NS_IMETHOD
-  Available(PRUint32* aAvailable) MOZ_OVERRIDE
+  Available(PRUint64* aAvailable) MOZ_OVERRIDE
   {
     // See large comment in FileInputStreamWrapper::Available.
     if (NS_IsMainThread()) {
       return NS_BASE_STREAM_CLOSED;
     }
 
     nsresult rv = BlockAndWaitForStream();
     NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/src/json/nsJSON.cpp
+++ b/dom/src/json/nsJSON.cpp
@@ -433,33 +433,38 @@ nsJSON::DecodeInternal(JSContext* cx,
   rv = jsonListener->OnStartRequest(jsonChannel, nullptr);
   if (NS_FAILED(rv)) {
     jsonChannel->Cancel(rv);
     return rv;
   }
 
   nsresult status;
   jsonChannel->GetStatus(&status);
-  PRUint32 offset = 0;
+  PRUint64 offset = 0;
   while (NS_SUCCEEDED(status)) {
-    PRUint32 available;
+    PRUint64 available;
     rv = aStream->Available(&available);
     if (rv == NS_BASE_STREAM_CLOSED) {
       rv = NS_OK;
       break;
     }
     if (NS_FAILED(rv)) {
       jsonChannel->Cancel(rv);
       break;
     }
     if (!available)
       break; // blocking input stream has none available when done
 
+    if (available > PR_UINT32_MAX)
+      available = PR_UINT32_MAX;
+
     rv = jsonListener->OnDataAvailable(jsonChannel, nullptr,
-                                       aStream, offset, available);
+                                       aStream,
+                                       (PRUint32)NS_MIN(offset, (PRUint64)PR_UINT32_MAX),
+                                       (PRUint32)available);
     if (NS_FAILED(rv)) {
       jsonChannel->Cancel(rv);
       break;
     }
 
     offset += available;
     jsonChannel->GetStatus(&status);
   }
--- a/extensions/gio/nsGIOProtocolHandler.cpp
+++ b/extensions/gio/nsGIOProtocolHandler.cpp
@@ -140,17 +140,17 @@ class nsGIOInputStream : public nsIInput
     NS_DECL_ISUPPORTS
     NS_DECL_NSIINPUTSTREAM
 
     nsGIOInputStream(const nsCString &uriSpec)
       : mSpec(uriSpec)
       , mChannel(nullptr)
       , mHandle(nullptr)
       , mStream(nullptr)
-      , mBytesRemaining(PR_UINT32_MAX)
+      , mBytesRemaining(PR_UINT64_MAX)
       , mStatus(NS_OK)
       , mDirList(nullptr)
       , mDirListPtr(nullptr)
       , mDirBufCursor(0)
       , mDirOpen(false)
       , mMonitorMountInProgress("GIOInputStream::MountFinished") { }
 
    ~nsGIOInputStream() { Close(); }
@@ -629,27 +629,22 @@ nsGIOInputStream::Close()
   return NS_OK;
 }
 
 /**
  * Return number of remaining bytes available on input
  * @param aResult remaining bytes
  */
 NS_IMETHODIMP
-nsGIOInputStream::Available(PRUint32 *aResult)
+nsGIOInputStream::Available(PRUint64 *aResult)
 {
   if (NS_FAILED(mStatus))
     return mStatus;
 
-  /* When remaining bytes are bigger than max PRUint32 value an aResult must
-     be set to PRUint32 maximum */
-  if (mBytesRemaining > PR_UINT32_MAX)
-    *aResult = PR_UINT32_MAX;
-  else
-    *aResult = mBytesRemaining;
+  *aResult = mBytesRemaining;
 
   return NS_OK;
 }
 
 /**
  * Trying to read from stream. When location is not available it tries to mount it.
  * @param aBuf buffer to put read data
  * @param aCount length of aBuf
--- a/extensions/gnomevfs/nsGnomeVFSProtocolHandler.cpp
+++ b/extensions/gnomevfs/nsGnomeVFSProtocolHandler.cpp
@@ -314,17 +314,17 @@ class nsGnomeVFSInputStream MOZ_FINAL : 
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIINPUTSTREAM
 
     nsGnomeVFSInputStream(const nsCString &uriSpec)
       : mSpec(uriSpec)
       , mChannel(nullptr)
       , mHandle(nullptr)
-      , mBytesRemaining(PR_UINT32_MAX)
+      , mBytesRemaining(PR_UINT64_MAX)
       , mStatus(NS_OK)
       , mDirList(nullptr)
       , mDirListPtr(nullptr)
       , mDirBufCursor(0)
       , mDirOpen(false) {}
 
    ~nsGnomeVFSInputStream() { Close(); }
 
@@ -350,17 +350,17 @@ class nsGnomeVFSInputStream MOZ_FINAL : 
     GnomeVFSResult DoOpen();
     GnomeVFSResult DoRead(char *aBuf, PRUint32 aCount, PRUint32 *aCountRead);
     nsresult       SetContentTypeOfChannel(const char *contentType);
 
   private:
     nsCString                mSpec;
     nsIChannel              *mChannel; // manually refcounted
     GnomeVFSHandle          *mHandle;
-    PRUint32                 mBytesRemaining;
+    PRUint64                 mBytesRemaining;
     nsresult                 mStatus;
     GList                   *mDirList;
     GList                   *mDirListPtr;
     nsCString                mDirBuf;
     PRUint32                 mDirBufCursor;
     bool                     mDirOpen;
 };
 
@@ -424,23 +424,24 @@ nsGnomeVFSInputStream::DoOpen()
       // type determined by GnomeVFS.  However, if GnomeVFS is telling us that
       // the document is binary, we'll ignore that and keep the channel's
       // content type unspecified.  That will enable our content type sniffing
       // algorithms.  This should provide more consistent mime type handling.
 
       if (info.mime_type && (strcmp(info.mime_type, APPLICATION_OCTET_STREAM) != 0))
         SetContentTypeOfChannel(info.mime_type);
 
-      // XXX truncates size from 64-bit to 32-bit
-      mBytesRemaining = (PRUint32) info.size;
+      mBytesRemaining = info.size;
 
       // Update the content length attribute on the channel.  We do this
       // synchronously without proxying.  This hack is not as bad as it looks!
-      if (mBytesRemaining != PR_UINT32_MAX)
-        mChannel->SetContentLength(mBytesRemaining);
+      if (mBytesRemaining != PR_UINT64_MAX) {
+        // XXX 64-bit
+        mChannel->SetContentLength(NS_MAX((PRInt32)mBytesRemaining, PR_INT32_MAX));
+      }
     }
     else
     {
       mDirOpen = true;
 
       // Sort mDirList
       mDirList = g_list_sort(mDirList, FileInfoComparator);
       mDirListPtr = mDirList;
@@ -473,16 +474,17 @@ nsGnomeVFSInputStream::DoRead(char *aBuf
   GnomeVFSResult rv;
 
   if (mHandle)
   {
     GnomeVFSFileSize bytesRead;
     rv = gnome_vfs_read(mHandle, aBuf, aCount, &bytesRead);
     if (rv == GNOME_VFS_OK)
     {
+      // aCount is 32-bit, so aCountRead is under 32-bit value.
       *aCountRead = (PRUint32) bytesRead;
       mBytesRemaining -= *aCountRead;
     }
   }
   else if (mDirOpen)
   {
     rv = GNOME_VFS_OK;
 
@@ -663,17 +665,17 @@ nsGnomeVFSInputStream::Close()
   // Prevent future reads from re-opening the handle.
   if (NS_SUCCEEDED(mStatus))
     mStatus = NS_BASE_STREAM_CLOSED;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsGnomeVFSInputStream::Available(PRUint32 *aResult)
+nsGnomeVFSInputStream::Available(PRUint64 *aResult)
 {
   if (NS_FAILED(mStatus))
     return mStatus;
 
   *aResult = mBytesRemaining;
   return NS_OK;
 }
 
--- a/extensions/pref/autoconfig/src/nsReadConfig.cpp
+++ b/extensions/pref/autoconfig/src/nsReadConfig.cpp
@@ -273,24 +273,31 @@ nsresult nsReadConfig::openAndEvaluateJS
         if (NS_FAILED(rv))
             return rv;
 
         rv = channel->Open(getter_AddRefs(inStr));
         if (NS_FAILED(rv)) 
             return rv;
     }
 
-    PRUint32 fs, amt = 0;
-    inStr->Available(&fs);
+    PRUint64 fs64;
+    PRUint32 amt = 0;
+    rv = inStr->Available(&fs64);
+    if (NS_FAILED(rv))
+        return rv;
+    // PR_Malloc dones't support over 4GB
+    if (fs64 > PR_UINT32_MAX)
+      return NS_ERROR_FILE_TOO_BIG;
+    PRUint32 fs = (PRUint32)fs64;
 
     char *buf = (char *)PR_Malloc(fs * sizeof(char));
     if (!buf) 
         return NS_ERROR_OUT_OF_MEMORY;
 
-    rv = inStr->Read(buf, fs, &amt);
+    rv = inStr->Read(buf, (PRUint32)fs, &amt);
     NS_ASSERTION((amt == fs), "failed to read the entire configuration file!!");
     if (NS_SUCCEEDED(rv)) {
         if (obscureValue > 0) {
 
             // Unobscure file by subtracting some value from every char. 
             for (PRUint32 i = 0; i < amt; i++)
                 buf[i] -= obscureValue;
         }
--- a/gfx/thebes/gfxASurface.cpp
+++ b/gfx/thebes/gfxASurface.cpp
@@ -744,21 +744,26 @@ gfxASurface::WriteAsPNG_internal(FILE* a
   if (NS_FAILED(rv))
     return;
 
   nsCOMPtr<nsIInputStream> imgStream;
   CallQueryInterface(encoder.get(), getter_AddRefs(imgStream));
   if (!imgStream)
     return;
 
-  PRUint32 bufSize;
-  rv = imgStream->Available(&bufSize);
+  PRUint64 bufSize64;
+  rv = imgStream->Available(&bufSize64);
   if (NS_FAILED(rv))
     return;
 
+  if (bufSize64 > PR_UINT32_MAX - 16)
+    return;
+
+  PRUint32 bufSize = (PRUint32)bufSize64;
+
   // ...leave a little extra room so we can call read again and make sure we
   // got everything. 16 bytes for better padding (maybe)
   bufSize += 16;
   PRUint32 imgSize = 0;
   char* imgData = (char*)PR_Malloc(bufSize);
   if (!imgData)
     return;
   PRUint32 numReadThisTime = 0;
--- a/image/encoders/bmp/nsBMPEncoder.cpp
+++ b/image/encoders/bmp/nsBMPEncoder.cpp
@@ -316,17 +316,17 @@ NS_IMETHODIMP nsBMPEncoder::Close()
     mImageBufferReadPoint = 0;
     mImageBufferCurr = nullptr;
   }
 
   return NS_OK;
 }
 
 // Obtains the available bytes to read
-NS_IMETHODIMP nsBMPEncoder::Available(PRUint32 *_retval)
+NS_IMETHODIMP nsBMPEncoder::Available(PRUint64 *_retval)
 {
   if (!mImageBufferStart || !mImageBufferCurr) {
     return NS_BASE_STREAM_CLOSED;
   }
 
   *_retval = GetCurrentImageBufferOffset() - mImageBufferReadPoint;
   return NS_OK;
 }
--- a/image/encoders/ico/nsICOEncoder.cpp
+++ b/image/encoders/ico/nsICOEncoder.cpp
@@ -329,17 +329,17 @@ NS_IMETHODIMP nsICOEncoder::Close()
     mImageBufferReadPoint = 0;
     mImageBufferCurr = nullptr;
   }
 
   return NS_OK;
 }
 
 // Obtains the available bytes to read
-NS_IMETHODIMP nsICOEncoder::Available(PRUint32 *_retval)
+NS_IMETHODIMP nsICOEncoder::Available(PRUint64 *_retval)
 {
   if (!mImageBufferStart || !mImageBufferCurr) {
     return NS_BASE_STREAM_CLOSED;
   }
 
   *_retval = GetCurrentImageBufferOffset() - mImageBufferReadPoint;
   return NS_OK;
 }
--- a/image/encoders/jpeg/nsJPEGEncoder.cpp
+++ b/image/encoders/jpeg/nsJPEGEncoder.cpp
@@ -231,17 +231,17 @@ NS_IMETHODIMP nsJPEGEncoder::Close()
     mImageBufferSize = 0;
     mImageBufferUsed = 0;
     mImageBufferReadPoint = 0;
   }
   return NS_OK;
 }
 
 /* unsigned long available (); */
-NS_IMETHODIMP nsJPEGEncoder::Available(PRUint32 *_retval)
+NS_IMETHODIMP nsJPEGEncoder::Available(PRUint64 *_retval)
 {
   if (!mImageBuffer)
     return NS_BASE_STREAM_CLOSED;
 
   *_retval = mImageBufferUsed - mImageBufferReadPoint;
   return NS_OK;
 }
 
--- a/image/encoders/png/nsPNGEncoder.cpp
+++ b/image/encoders/png/nsPNGEncoder.cpp
@@ -487,17 +487,17 @@ NS_IMETHODIMP nsPNGEncoder::Close()
     mImageBufferSize = 0;
     mImageBufferUsed = 0;
     mImageBufferReadPoint = 0;
   }
   return NS_OK;
 }
 
 /* unsigned long available (); */
-NS_IMETHODIMP nsPNGEncoder::Available(PRUint32 *_retval)
+NS_IMETHODIMP nsPNGEncoder::Available(PRUint64 *_retval)
 {
   if (!mImageBuffer)
     return NS_BASE_STREAM_CLOSED;
 
   *_retval = mImageBufferUsed - mImageBufferReadPoint;
   return NS_OK;
 }
 
--- a/image/src/imgTools.cpp
+++ b/image/src/imgTools.cpp
@@ -69,26 +69,27 @@ NS_IMETHODIMP imgTools::DecodeImageData(
   if (!NS_InputStreamIsBuffered(aInStr)) {
     nsCOMPtr<nsIInputStream> bufStream;
     rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), aInStr, 1024);
     if (NS_SUCCEEDED(rv))
       inStream = bufStream;
   }
 
   // Figure out how much data we've been passed
-  PRUint32 length;
+  PRUint64 length;
   rv = inStream->Available(&length);
   NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(length <= PR_UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
 
   // Send the source data to the Image. WriteToRasterImage always
   // consumes everything it gets if it doesn't run out of memory.
   PRUint32 bytesRead;
   rv = inStream->ReadSegments(RasterImage::WriteToRasterImage,
                               static_cast<void*>(image),
-                              length, &bytesRead);
+                              (PRUint32)length, &bytesRead);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ABORT_IF_FALSE(bytesRead == length || image->HasError(),
   "WriteToRasterImage should consume everything or the image must be in error!");
 
   // Let the Image know we've sent all the data
   rv = image->SourceDataComplete();
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -850,22 +850,25 @@ mozJSComponentLoader::GlobalForLocation(
             nsCOMPtr<nsIChannel> scriptChannel;
             rv = ioService->NewChannelFromURI(aURI, getter_AddRefs(scriptChannel));
             NS_ENSURE_SUCCESS(rv, rv);
 
             nsCOMPtr<nsIInputStream> scriptStream;
             rv = scriptChannel->Open(getter_AddRefs(scriptStream));
             NS_ENSURE_SUCCESS(rv, rv);
 
-            PRUint32 len, bytesRead;
+            PRUint64 len64;
+            PRUint32 bytesRead;
 
-            rv = scriptStream->Available(&len);
+            rv = scriptStream->Available(&len64);
             NS_ENSURE_SUCCESS(rv, rv);
-            if (!len)
+            NS_ENSURE_TRUE(len64 < PR_UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
+            if (!len64)
                 return NS_ERROR_FAILURE;
+            PRUint32 len = (PRUint32)len64;
 
             /* malloc an internal buf the size of the file */
             nsAutoArrayPtr<char> buf(new char[len + 1]);
             if (!buf)
                 return NS_ERROR_OUT_OF_MEMORY;
 
             /* read the file in one swoop */
             rv = scriptStream->Read(buf, len, &bytesRead);
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -8138,18 +8138,23 @@ DumpToPNG(nsIPresShell* shell, nsAString
                         imgIEncoder::INPUT_FORMAT_HOSTARGB, EmptyString());
 
   // XXX not sure if this is the right way to write to a file
   nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
   NS_ENSURE_TRUE(file, NS_ERROR_FAILURE);
   rv = file->InitWithPath(name);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRUint32 length;
-  encoder->Available(&length);
+  PRUint64 length64;
+  rv = encoder->Available(&length64);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (length64 > PR_UINT32_MAX)
+    return NS_ERROR_FILE_TOO_BIG;
+
+  PRUint32 length = (PRUint32)length64;
 
   nsCOMPtr<nsIOutputStream> outputStream;
   rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), file);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIOutputStream> bufferedOutputStream;
   rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
                                   outputStream, length);
--- a/layout/style/nsFontFaceLoader.cpp
+++ b/layout/style/nsFontFaceLoader.cpp
@@ -868,21 +868,26 @@ nsUserFontSet::SyncLoadFontData(gfxProxy
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // blocking stream is OK for data URIs
   nsCOMPtr<nsIInputStream> stream;
   rv = channel->Open(getter_AddRefs(stream));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = stream->Available(&aBufferLength);
+  PRUint64 bufferLength64;
+  rv = stream->Available(&bufferLength64);
   NS_ENSURE_SUCCESS(rv, rv);
-  if (aBufferLength == 0) {
+  if (bufferLength64 == 0) {
     return NS_ERROR_FAILURE;
   }
+  if (bufferLength64 > PR_UINT32_MAX) {
+    return NS_ERROR_FILE_TOO_BIG;
+  }
+  aBufferLength = static_cast<PRUint32>(bufferLength64);
 
   // read all the decoded data
   aBuffer = static_cast<PRUint8*> (NS_Alloc(sizeof(PRUint8) * aBufferLength));
   if (!aBuffer) {
     aBufferLength = 0;
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
--- a/modules/libjar/nsJAR.cpp
+++ b/modules/libjar/nsJAR.cpp
@@ -417,21 +417,21 @@ nsJAR::LoadEntry(const nsACString &aFile
   //-- Get a stream for reading the file
   nsresult rv;
   nsCOMPtr<nsIInputStream> manifestStream;
   rv = GetInputStream(aFilename, getter_AddRefs(manifestStream));
   if (NS_FAILED(rv)) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST;
   
   //-- Read the manifest file into memory
   char* buf;
-  PRUint32 len;
-  rv = manifestStream->Available(&len);
+  PRUint64 len64;
+  rv = manifestStream->Available(&len64);
   if (NS_FAILED(rv)) return rv;
-  if (len == PRUint32(-1))
-    return NS_ERROR_FILE_CORRUPTED; // bug 164695
+  NS_ENSURE_TRUE(len64 < PR_UINT32_MAX, NS_ERROR_FILE_CORRUPTED); // bug 164695
+  PRUint32 len = (PRUint32)len64;
   buf = (char*)malloc(len+1);
   if (!buf) return NS_ERROR_OUT_OF_MEMORY;
   PRUint32 bytesRead;
   rv = manifestStream->Read(buf, len, &bytesRead);
   if (bytesRead != len) 
     rv = NS_ERROR_FILE_CORRUPTED;
   if (NS_FAILED(rv)) {
     free(buf);
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -127,33 +127,36 @@ nsJARInputThunk::EnsureJarStream()
         // convert to the proper result if the entry wasn't found
         // so that error pages work
         if (rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
             rv = NS_ERROR_FILE_NOT_FOUND;
         return rv;
     }
 
     // ask the JarStream for the content length
-    rv = mJarStream->Available((PRUint32 *) &mContentLength);
+    PRUint64 avail;
+    rv = mJarStream->Available((PRUint64 *) &avail);
     if (NS_FAILED(rv)) return rv;
 
+    mContentLength = avail < PR_INT32_MAX ? (PRInt32) avail : -1;
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsJARInputThunk::Close()
 {
     if (mJarStream)
         return mJarStream->Close();
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsJARInputThunk::Available(PRUint32 *avail)
+nsJARInputThunk::Available(PRUint64 *avail)
 {
     nsresult rv = EnsureJarStream();
     if (NS_FAILED(rv)) return rv;
 
     return mJarStream->Available(avail);
 }
 
 NS_IMETHODIMP
--- a/modules/libjar/nsJARInputStream.cpp
+++ b/modules/libjar/nsJARInputStream.cpp
@@ -141,17 +141,17 @@ nsJARInputStream::InitDirectory(nsJAR* a
     // Open for reading
     mMode = MODE_DIRECTORY;
     mZs.total_out = 0;
     mArrPos = 0;
     return NS_OK;
 }
 
 NS_IMETHODIMP 
-nsJARInputStream::Available(PRUint32 *_retval)
+nsJARInputStream::Available(PRUint64 *_retval)
 {
     // A lot of callers don't check the error code.
     // They just use the _retval value.
     *_retval = 0;
 
     switch (mMode) {
       case MODE_NOTINITED:
         break;
--- a/modules/libpref/src/Preferences.cpp
+++ b/modules/libpref/src/Preferences.cpp
@@ -445,17 +445,18 @@ ReadExtensionPrefs(nsIFile *aFile)
     nsCAutoString entry;
     rv = files->GetNext(entry);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIInputStream> stream;
     rv = reader->GetInputStream(entry, getter_AddRefs(stream));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    PRUint32 avail, read;
+    PRUint64 avail;
+    PRUint32 read;
 
     PrefParseState ps;
     PREF_InitParseState(&ps, PREF_ReaderCallback, NULL);
     while (NS_SUCCEEDED(rv = stream->Available(&avail)) && avail) {
       rv = stream->Read(buffer, 4096, &read);
       if (NS_FAILED(rv)) {
         NS_WARNING("Pref stream read failed");
         break;
@@ -754,21 +755,23 @@ Preferences::WritePrefFile(nsIFile* aFil
 static nsresult openPrefFile(nsIFile* aFile)
 {
   nsCOMPtr<nsIInputStream> inStr;
 
   nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), aFile);
   if (NS_FAILED(rv)) 
     return rv;        
 
-  PRUint32 fileSize;
-  rv = inStr->Available(&fileSize);
+  PRUint64 fileSize64;
+  rv = inStr->Available(&fileSize64);
   if (NS_FAILED(rv))
     return rv;
+  NS_ENSURE_TRUE(fileSize64 <= PR_UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
 
+  PRUint32 fileSize = (PRUint32)fileSize64;
   nsAutoArrayPtr<char> fileBuffer(new char[fileSize]);
   if (fileBuffer == nullptr)
     return NS_ERROR_OUT_OF_MEMORY;
 
   PrefParseState ps;
   PREF_InitParseState(&ps, PREF_ReaderCallback, NULL);
 
   // Read is not guaranteed to return a buf the size of fileSize,
--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -634,17 +634,17 @@ NS_ImplementChannelOpen(nsIChannel      
 {
     nsCOMPtr<nsIStreamListener> listener;
     nsCOMPtr<nsIInputStream> stream;
     nsresult rv = NS_NewSyncStreamListener(getter_AddRefs(listener),
                                            getter_AddRefs(stream));
     if (NS_SUCCEEDED(rv)) {
         rv = channel->AsyncOpen(listener, nullptr);
         if (NS_SUCCEEDED(rv)) {
-            PRUint32 n;
+            PRUint64 n;
             // block until the initial response is received or an error occurs.
             rv = stream->Available(&n);
             if (NS_SUCCEEDED(rv)) {
                 *result = nullptr;
                 stream.swap(*result);
             }
         }
     }
--- a/netwerk/base/src/nsBaseContentStream.cpp
+++ b/netwerk/base/src/nsBaseContentStream.cpp
@@ -50,17 +50,17 @@ NS_INTERFACE_MAP_END_THREADSAFE
 
 NS_IMETHODIMP
 nsBaseContentStream::Close()
 {
   return IsClosed() ? NS_OK : CloseWithStatus(NS_BASE_STREAM_CLOSED);
 }
 
 NS_IMETHODIMP
-nsBaseContentStream::Available(PRUint32 *result)
+nsBaseContentStream::Available(PRUint64 *result)
 {
   *result = 0;
   return mStatus;
 }
 
 NS_IMETHODIMP
 nsBaseContentStream::Read(char *buf, PRUint32 count, PRUint32 *result)
 {
--- a/netwerk/base/src/nsBufferedStreams.cpp
+++ b/netwerk/base/src/nsBufferedStreams.cpp
@@ -292,17 +292,17 @@ nsBufferedInputStream::Close()
         NS_RELEASE(mStream);
     }
     rv2 = nsBufferedStream::Close();
     if (NS_FAILED(rv1)) return rv1;
     return rv2;
 }
 
 NS_IMETHODIMP
-nsBufferedInputStream::Available(PRUint32 *result)
+nsBufferedInputStream::Available(PRUint64 *result)
 {
     nsresult rv = NS_OK;
     *result = 0;
     if (mStream) {
         rv = Source()->Available(result);
     }
     *result += (mFillPoint - mCursor);
     return rv;
--- a/netwerk/base/src/nsDirectoryIndexStream.cpp
+++ b/netwerk/base/src/nsDirectoryIndexStream.cpp
@@ -195,17 +195,17 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsDirector
 NS_IMETHODIMP
 nsDirectoryIndexStream::Close()
 {
     mStatus = NS_BASE_STREAM_CLOSED;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDirectoryIndexStream::Available(PRUint32* aLength)
+nsDirectoryIndexStream::Available(PRUint64* aLength)
 {
     if (NS_FAILED(mStatus))
         return mStatus;
 
     // If there's data in our buffer, use that
     if (mOffset < (PRInt32)mBuf.Length()) {
         *aLength = mBuf.Length() - mOffset;
         return NS_OK;
--- a/netwerk/base/src/nsFileStreams.cpp
+++ b/netwerk/base/src/nsFileStreams.cpp
@@ -129,34 +129,34 @@ nsFileStreamBase::Close()
         if (PR_Close(mFD) == PR_FAILURE)
             rv = NS_BASE_STREAM_OSERROR;
         mFD = nullptr;
     }
     return rv;
 }
 
 nsresult
-nsFileStreamBase::Available(PRUint32* aResult)
+nsFileStreamBase::Available(PRUint64* aResult)
 {
     nsresult rv = DoPendingOpen();
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (!mFD) {
         return NS_BASE_STREAM_CLOSED;
     }
 
     // PR_Available with files over 4GB returns an error, so we have to
     // use the 64-bit version of PR_Available.
     PRInt64 avail = PR_Available64(mFD);
     if (avail == -1) {
         return NS_ErrorAccordingToNSPR();
     }
 
     // If available is greater than 4GB, return 4GB
-    *aResult = avail > PR_UINT32_MAX ? PR_UINT32_MAX : (PRUint32)avail;
+    *aResult = (PRUint64)avail;
     return NS_OK;
 }
 
 nsresult
 nsFileStreamBase::Read(char* aBuf, PRUint32 aCount, PRUint32* aResult)
 {
     nsresult rv = DoPendingOpen();
     NS_ENSURE_SUCCESS(rv, rv);
@@ -568,30 +568,30 @@ nsPartialFileInputStream::Tell(PRInt64 *
     nsresult rv = nsFileInputStream::Tell(&tell);
     if (NS_SUCCEEDED(rv)) {
         *aResult = tell - mStart;
     }
     return rv;
 }
 
 NS_IMETHODIMP
-nsPartialFileInputStream::Available(PRUint32* aResult)
+nsPartialFileInputStream::Available(PRUint64* aResult)
 {
-    PRUint32 available;
+    PRUint64 available;
     nsresult rv = nsFileInputStream::Available(&available);
     if (NS_SUCCEEDED(rv)) {
         *aResult = TruncateSize(available);
     }
     return rv;
 }
 
 NS_IMETHODIMP
 nsPartialFileInputStream::Read(char* aBuf, PRUint32 aCount, PRUint32* aResult)
 {
-    PRUint32 readsize = TruncateSize(aCount);
+    PRUint32 readsize = (PRUint32) TruncateSize(aCount);
     if (readsize == 0 && mBehaviorFlags & CLOSE_ON_EOF) {
         Close();
         *aResult = 0;
         return NS_OK;
     }
 
     nsresult rv = nsFileInputStream::Read(aBuf, readsize, aResult);
     if (NS_SUCCEEDED(rv)) {
--- a/netwerk/base/src/nsFileStreams.h
+++ b/netwerk/base/src/nsFileStreams.h
@@ -29,17 +29,17 @@ public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSISEEKABLESTREAM
 
     nsFileStreamBase();
     virtual ~nsFileStreamBase();
 
 protected:
     nsresult Close();
-    nsresult Available(PRUint32* _retval);
+    nsresult Available(PRUint64* _retval);
     nsresult Read(char* aBuf, PRUint32 aCount, PRUint32* _retval);
     nsresult ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
                           PRUint32 aCount, PRUint32* _retval);
     nsresult IsNonBlocking(bool* _retval);
     nsresult Flush();
     nsresult Write(const char* aBuf, PRUint32 aCount, PRUint32* _retval);
     nsresult WriteFrom(nsIInputStream* aFromStream, PRUint32 aCount,
                        PRUint32* _retval);
@@ -106,17 +106,17 @@ class nsFileInputStream : public nsFileS
 {
 public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIFILEINPUTSTREAM
     NS_DECL_NSILINEINPUTSTREAM
     NS_DECL_NSIIPCSERIALIZABLE
 
     NS_IMETHOD Close();
-    NS_IMETHOD Available(PRUint32* _retval)
+    NS_IMETHOD Available(PRUint64* _retval)
     {
         return nsFileStreamBase::Available(_retval);
     }
     NS_IMETHOD Read(char* aBuf, PRUint32 aCount, PRUint32* _retval);
     NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
                             PRUint32 aCount, PRUint32* _retval)
     {
         return nsFileStreamBase::ReadSegments(aWriter, aClosure, aCount,
@@ -177,26 +177,26 @@ class nsPartialFileInputStream : public 
 {
 public:
     using nsFileInputStream::Init;
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIPARTIALFILEINPUTSTREAM
     NS_DECL_NSIIPCSERIALIZABLE
 
     NS_IMETHOD Tell(PRInt64 *aResult);
-    NS_IMETHOD Available(PRUint32 *aResult);
+    NS_IMETHOD Available(PRUint64 *aResult);
     NS_IMETHOD Read(char* aBuf, PRUint32 aCount, PRUint32* aResult);
     NS_IMETHOD Seek(PRInt32 aWhence, PRInt64 aOffset);
 
     static nsresult
     Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
 
 private:
-    PRUint32 TruncateSize(PRUint32 aSize) {
-          return (PRUint32)NS_MIN<PRUint64>(mLength - mPosition, aSize);
+    PRUint64 TruncateSize(PRUint64 aSize) {
+          return NS_MIN<PRUint64>(mLength - mPosition, aSize);
     }
 
     PRUint64 mStart;
     PRUint64 mLength;
     PRUint64 mPosition;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/netwerk/base/src/nsInputStreamChannel.cpp
+++ b/netwerk/base/src/nsInputStreamChannel.cpp
@@ -14,17 +14,17 @@ nsInputStreamChannel::OpenContentStream(
 {
   NS_ENSURE_TRUE(mContentStream, NS_ERROR_NOT_INITIALIZED);
 
   // If content length is unknown, then we must guess.  In this case, we assume
   // the stream can tell us.  If the stream is a pipe, then this will not work.
 
   PRInt64 len = ContentLength64();
   if (len < 0) {
-    PRUint32 avail;
+    PRUint64 avail;
     nsresult rv = mContentStream->Available(&avail);
     if (rv == NS_BASE_STREAM_CLOSED) {
       // This just means there's nothing in the stream
       avail = 0;
     } else if (NS_FAILED(rv)) {
       return rv;
     }
     SetContentLength64(avail);
--- a/netwerk/base/src/nsInputStreamPump.cpp
+++ b/netwerk/base/src/nsInputStreamPump.cpp
@@ -96,20 +96,21 @@ CallPeekFunc(nsIInputStream *aInStream, 
 }
 
 nsresult
 nsInputStreamPump::PeekStream(PeekSegmentFun callback, void* closure)
 {
   NS_ASSERTION(mAsyncStream, "PeekStream called without stream");
 
   // See if the pipe is closed by checking the return of Available.
-  PRUint32 dummy;
-  nsresult rv = mAsyncStream->Available(&dummy);
+  PRUint64 dummy64;
+  nsresult rv = mAsyncStream->Available(&dummy64);
   if (NS_FAILED(rv))
     return rv;
+  PRUint32 dummy = (PRUint32)NS_MIN(dummy64, (PRUint64)PR_UINT32_MAX);
 
   PeekData data(callback, closure);
   return mAsyncStream->ReadSegments(CallPeekFunc,
                                     &data,
                                     nsIOService::gDefaultSegmentSize,
                                     &dummy);
 }
 
@@ -402,17 +403,17 @@ nsInputStreamPump::OnStateStart()
     LOG(("  OnStateStart [this=%x]\n", this));
 
     nsresult rv;
 
     // need to check the reason why the stream is ready.  this is required
     // so our listener can check our status from OnStartRequest.
     // XXX async streams should have a GetStatus method!
     if (NS_SUCCEEDED(mStatus)) {
-        PRUint32 avail;
+        PRUint64 avail;
         rv = mAsyncStream->Available(&avail);
         if (NS_FAILED(rv) && rv != NS_BASE_STREAM_CLOSED)
             mStatus = rv;
     }
 
     rv = mListener->OnStartRequest(this, mListenerContext);
 
     // an error returned from OnStartRequest should cause us to abort; however,
@@ -430,28 +431,28 @@ nsInputStreamPump::OnStateTransfer()
     LOG(("  OnStateTransfer [this=%x]\n", this));
 
     // if canceled, go directly to STATE_STOP...
     if (NS_FAILED(mStatus))
         return STATE_STOP;
 
     nsresult rv;
 
-    PRUint32 avail;
+    PRUint64 avail;
     rv = mAsyncStream->Available(&avail);
-    LOG(("  Available returned [stream=%x rv=%x avail=%u]\n", mAsyncStream.get(), rv, avail));
+    LOG(("  Available returned [stream=%x rv=%x avail=%llu]\n", mAsyncStream.get(), rv, avail));
 
     if (rv == NS_BASE_STREAM_CLOSED) {
         rv = NS_OK;
         avail = 0;
     }
     else if (NS_SUCCEEDED(rv) && avail) {
         // figure out how much data to report (XXX detect overflow??)
-        if (PRUint64(avail) + mStreamOffset > mStreamLength)
-            avail = PRUint32(mStreamLength - mStreamOffset);
+        if (avail > mStreamLength - mStreamOffset)
+            avail = mStreamLength - mStreamOffset;
 
         if (avail) {
             // we used to limit avail to 16K - we were afraid some ODA handlers
             // might assume they wouldn't get more than 16K at once
             // we're removing that limit since it speeds up local file access.
             // Now there's an implicit 64K limit of 4 16K segments
             // NOTE: ok, so the story is as follows.  OnDataAvailable impls
             //       are by contract supposed to consume exactly |avail| bytes.
@@ -473,48 +474,51 @@ nsInputStreamPump::OnStateTransfer()
 
             // report the current stream offset to our listener... if we've
             // streamed more than PR_UINT32_MAX, then avoid overflowing the
             // stream offset.  it's the best we can do without a 64-bit stream
             // listener API.
             PRUint32 odaOffset =
                 mStreamOffset > PR_UINT32_MAX ?
                 PR_UINT32_MAX : PRUint32(mStreamOffset);
+            PRUint32 odaAvail =
+                avail > PR_UINT32_MAX ?
+                PR_UINT32_MAX : PRUint32(avail);
 
-            LOG(("  calling OnDataAvailable [offset=%lld(%u) count=%u]\n",
-                mStreamOffset, odaOffset, avail));
+            LOG(("  calling OnDataAvailable [offset=%lld(%u) count=%llu(%u)]\n",
+                mStreamOffset, odaOffset, avail, odaAvail));
 
             rv = mListener->OnDataAvailable(this, mListenerContext, mAsyncStream,
-                                            odaOffset, avail);
+                                            odaOffset, odaAvail);
 
             // don't enter this code if ODA failed or called Cancel
             if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(mStatus)) {
                 // test to see if this ODA failed to consume data
                 if (seekable) {
                     // NOTE: if Tell fails, which can happen if the stream is
                     // now closed, then we assume that everything was read.
                     PRInt64 offsetAfter;
                     if (NS_FAILED(seekable->Tell(&offsetAfter)))
-                        offsetAfter = offsetBefore + avail;
+                        offsetAfter = offsetBefore + odaAvail;
                     if (offsetAfter > offsetBefore)
                         mStreamOffset += (offsetAfter - offsetBefore);
                     else if (mSuspendCount == 0) {
                         //
                         // possible infinite loop if we continue pumping data!
                         //
                         // NOTE: although not allowed by nsIStreamListener, we
                         // will allow the ODA impl to Suspend the pump.  IMAP
                         // does this :-(
                         //
                         NS_ERROR("OnDataAvailable implementation consumed no data");
                         mStatus = NS_ERROR_UNEXPECTED;
                     }
                 }
                 else
-                    mStreamOffset += avail; // assume ODA behaved well
+                    mStreamOffset += odaAvail; // assume ODA behaved well
             }
         }
     }
 
     // an error returned from Available or OnDataAvailable should cause us to
     // abort; however, we must not stomp on mStatus if already canceled.
 
     if (NS_SUCCEEDED(mStatus)) {
--- a/netwerk/base/src/nsMIMEInputStream.cpp
+++ b/netwerk/base/src/nsMIMEInputStream.cpp
@@ -165,22 +165,22 @@ void nsMIMEInputStream::InitStreams()
 {
     NS_ASSERTION(!mStartedReading,
                  "Don't call initStreams twice without rewinding");
 
     mStartedReading = true;
 
     // We'll use the content-length stream to add the final \r\n
     if (mAddContentLength) {
-        PRUint32 cl = 0;
+        PRUint64 cl = 0;
         if (mData) {
             mData->Available(&cl);
         }
         mContentLength.AssignLiteral("Content-Length: ");
-        mContentLength.AppendInt((PRInt32)cl);
+        mContentLength.AppendInt(cl);
         mContentLength.AppendLiteral("\r\n\r\n");
     }
     else {
         mContentLength.AssignLiteral("\r\n");
     }
     mCLStream->ShareData(mContentLength.get(), -1);
     mHeaderStream->ShareData(mHeaders.get(), -1);
 }
@@ -240,17 +240,17 @@ nsMIMEInputStream::ReadSegCb(nsIInputStr
 }
 
 /**
  * Forward everything else to the mStream after calling InitStreams()
  */
 
 // nsIInputStream
 NS_IMETHODIMP nsMIMEInputStream::Close(void) { INITSTREAMS; return mStream->Close(); }
-NS_IMETHODIMP nsMIMEInputStream::Available(PRUint32 *_retval) { INITSTREAMS; return mStream->Available(_retval); }
+NS_IMETHODIMP nsMIMEInputStream::Available(PRUint64 *_retval) { INITSTREAMS; return mStream->Available(_retval); }
 NS_IMETHODIMP nsMIMEInputStream::Read(char * buf, PRUint32 count, PRUint32 *_retval) { INITSTREAMS; return mStream->Read(buf, count, _retval); }
 NS_IMETHODIMP nsMIMEInputStream::IsNonBlocking(bool *aNonBlocking) { INITSTREAMS; return mStream->IsNonBlocking(aNonBlocking); }
 
 // nsISeekableStream
 NS_IMETHODIMP nsMIMEInputStream::Tell(PRInt64 *_retval)
 {
     INITSTREAMS;
     nsCOMPtr<nsISeekableStream> stream = do_QueryInterface(mStream);
--- a/netwerk/base/src/nsPreloadedStream.cpp
+++ b/netwerk/base/src/nsPreloadedStream.cpp
@@ -36,19 +36,19 @@ NS_IMETHODIMP
 nsPreloadedStream::Close()
 {
     mLen = 0;
     return mStream->Close();
 }
 
 
 NS_IMETHODIMP
-nsPreloadedStream::Available(PRUint32 *_retval)
+nsPreloadedStream::Available(PRUint64 *_retval)
 {
-    PRUint32 avail = 0;
+    PRUint64 avail = 0;
     
     nsresult rv = mStream->Available(&avail);
     if (NS_FAILED(rv))
         return rv;
     *_retval = avail + mLen;
     return NS_OK;
 }
 
--- a/netwerk/base/src/nsSocketTransport2.cpp
+++ b/netwerk/base/src/nsSocketTransport2.cpp
@@ -244,17 +244,17 @@ nsSocketInputStream::Release()
 
 NS_IMETHODIMP
 nsSocketInputStream::Close()
 {
     return CloseWithStatus(NS_BASE_STREAM_CLOSED);
 }
 
 NS_IMETHODIMP
-nsSocketInputStream::Available(PRUint32 *avail)
+nsSocketInputStream::Available(PRUint64 *avail)
 {
     SOCKET_LOG(("nsSocketInputStream::Available [this=%x]\n", this));
 
     *avail = 0;
 
     PRFileDesc *fd;
     {
         MutexAutoLock lock(mTransport->mLock);
--- a/netwerk/base/src/nsStreamTransportService.cpp
+++ b/netwerk/base/src/nsStreamTransportService.cpp
@@ -158,17 +158,17 @@ nsInputStreamTransport::Close()
         mSource->Close();
 
     // make additional reads return early...
     mOffset = mLimit = 0;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsInputStreamTransport::Available(PRUint32 *result)
+nsInputStreamTransport::Available(PRUint64 *result)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsInputStreamTransport::Read(char *buf, PRUint32 count, PRUint32 *result)
 {
     if (mFirstTime) {
--- a/netwerk/base/src/nsSyncStreamListener.cpp
+++ b/netwerk/base/src/nsSyncStreamListener.cpp
@@ -113,17 +113,17 @@ nsSyncStreamListener::Close()
     if (mPipeIn) {
         mPipeIn->Close();
         mPipeIn = nullptr;
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSyncStreamListener::Available(PRUint32 *result)
+nsSyncStreamListener::Available(PRUint64 *result)
 {
     if (NS_FAILED(mStatus))
         return mStatus;
 
     mStatus = mPipeIn->Available(result);
     if (NS_SUCCEEDED(mStatus) && (*result == 0) && !mDone) {
         mStatus = WaitForData();
         if (NS_SUCCEEDED(mStatus))
@@ -137,41 +137,41 @@ nsSyncStreamListener::Read(char     *buf
                            PRUint32  bufLen,
                            PRUint32 *result)
 {
     if (mStatus == NS_BASE_STREAM_CLOSED) {
         *result = 0;
         return NS_OK;
     }
 
-    PRUint32 avail;
-    if (NS_FAILED(Available(&avail)))
+    PRUint64 avail64;
+    if (NS_FAILED(Available(&avail64)))
         return mStatus;
 
-    avail = NS_MIN(avail, bufLen);
+    PRUint32 avail = (PRUint32)NS_MIN(avail64, (PRUint64)bufLen);
     mStatus = mPipeIn->Read(buf, avail, result);
     return mStatus;
 }
 
 NS_IMETHODIMP
 nsSyncStreamListener::ReadSegments(nsWriteSegmentFun  writer,
                                    void              *closure,
                                    PRUint32           count,
                                    PRUint32          *result)
 {
     if (mStatus == NS_BASE_STREAM_CLOSED) {
         *result = 0;
         return NS_OK;
     }
 
-    PRUint32 avail;
-    if (NS_FAILED(Available(&avail)))
+    PRUint64 avail64;
+    if (NS_FAILED(Available(&avail64)))
         return mStatus;
 
-    avail = NS_MIN(avail, count);
+    PRUint32 avail = (PRUint32)NS_MIN(avail64, (PRUint64)count);
     mStatus = mPipeIn->ReadSegments(writer, closure, avail, result);
     return mStatus;
 }
 
 NS_IMETHODIMP
 nsSyncStreamListener::IsNonBlocking(bool *result)
 {
     *result = false;
--- a/netwerk/cache/nsCacheEntryDescriptor.cpp
+++ b/netwerk/cache/nsCacheEntryDescriptor.cpp
@@ -557,17 +557,17 @@ nsInputStreamWrapper::Close()
 {
     nsresult rv = EnsureInit();
     if (NS_FAILED(rv)) return rv;
 
     return mInput->Close();
 }
 
 nsresult nsCacheEntryDescriptor::
-nsInputStreamWrapper::Available(PRUint32 *avail)
+nsInputStreamWrapper::Available(PRUint64 *avail)
 {
     nsresult rv = EnsureInit();
     if (NS_FAILED(rv)) return rv;
 
     return mInput->Available(avail);
 }
 
 nsresult nsCacheEntryDescriptor::
--- a/netwerk/cache/nsDiskCacheStreams.cpp
+++ b/netwerk/cache/nsDiskCacheStreams.cpp
@@ -88,17 +88,17 @@ nsDiskCacheInputStream::Close()
         }
         mClosed = true;
     }
     return NS_OK;
 }
 
 
 NS_IMETHODIMP
-nsDiskCacheInputStream::Available(PRUint32 * bytesAvailable)
+nsDiskCacheInputStream::Available(PRUint64 * bytesAvailable)
 {
     if (mClosed)  return NS_BASE_STREAM_CLOSED;
     if (mStreamEnd < mPos)  return NS_ERROR_UNEXPECTED;
     
     *bytesAvailable = mStreamEnd - mPos;
     return NS_OK;
 }
 
--- a/netwerk/ipc/NeckoMessageUtils.h
+++ b/netwerk/ipc/NeckoMessageUtils.h
@@ -173,22 +173,25 @@ struct ParamTraits<InputStream>
     nsCOMPtr<nsIIPCSerializable> serializable = do_QueryInterface(aParam.mStream);
     bool isSerializable = !!serializable;
     WriteParam(aMsg, isSerializable);
 
     if (!serializable) {
       NS_WARNING("nsIInputStream implementation doesn't support nsIIPCSerializable; falling back to copying data");
 
       nsCString streamString;
-      PRUint32 bytes;
+      PRUint64 bytes;
 
-      aParam.mStream->Available(&bytes);
-      if (bytes > 0) {
+      nsresult rv = aParam.mStream->Available(&bytes);
+      if (NS_SUCCEEDED(rv) && bytes > 0) {
+        // Also, on 64-bit system, for an interoperability for 32-bit process
+        // and 64-bit process, we shouldn't handle over 4GB message.
+        NS_ABORT_IF_FALSE(bytes < PR_UINT32_MAX, "nsIInputStream has over 4GB data");
         mozilla::DebugOnly<nsresult> rv =
-          NS_ReadInputStreamToString(aParam.mStream, streamString, bytes);
+          NS_ReadInputStreamToString(aParam.mStream, streamString, (PRUint32)bytes);
         NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "Can't read input stream into a string!");
       }
 
       WriteParam(aMsg, streamString);
       return;
     }
 
     nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(aParam.mStream);
--- a/netwerk/protocol/device/AndroidCaptureProvider.cpp
+++ b/netwerk/protocol/device/AndroidCaptureProvider.cpp
@@ -97,17 +97,17 @@ void AndroidCameraInputStream::ReceiveFr
     mAvailable += mFrameSize;
     mFrameQueue->Push((void*)fullFrame);
   }
 
   NotifyListeners();
 }
 
 NS_IMETHODIMP
-AndroidCameraInputStream::Available(PRUint32 *aAvailable)
+AndroidCameraInputStream::Available(PRUint64 *aAvailable)
 {
   mozilla::ReentrantMonitorAutoEnter autoMonitor(mMonitor);
 
   *aAvailable = mAvailable;
 
   return NS_OK;
 }
 
--- a/netwerk/protocol/device/GonkCaptureProvider.cpp
+++ b/netwerk/protocol/device/GonkCaptureProvider.cpp
@@ -388,17 +388,17 @@ GonkCameraInputStream::ReceiveFrame(char
     mAvailable += mFrameSize;
     mFrameQueue.Push((void*)fullFrame);
   }
 
   NotifyListeners();
 }
 
 NS_IMETHODIMP
-GonkCameraInputStream::Available(PRUint32 *aAvailable)
+GonkCameraInputStream::Available(PRUint64 *aAvailable)
 {
   ReentrantMonitorAutoEnter enter(mMonitor);
 
   *aAvailable = mAvailable;
 
   return NS_OK;
 }
 
--- a/netwerk/protocol/file/nsFileChannel.cpp
+++ b/netwerk/protocol/file/nsFileChannel.cpp
@@ -417,21 +417,22 @@ nsFileChannel::SetUploadStream(nsIInputS
                                PRInt32 contentLength)
 {
   NS_ENSURE_TRUE(!IsPending(), NS_ERROR_IN_PROGRESS);
 
   if ((mUploadStream = stream)) {
     mUploadLength = contentLength;
     if (mUploadLength < 0) {
       // Make sure we know how much data we are uploading.
-      PRUint32 avail;
+      PRUint64 avail;
       nsresult rv = mUploadStream->Available(&avail);
       if (NS_FAILED(rv))
         return rv;
-      mUploadLength = avail;
+      if (avail < PR_INT64_MAX)
+        mUploadLength = avail;
     }
   } else {
     mUploadLength = -1;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
@@ -2094,17 +2094,17 @@ nsFtpState::OnStopRequest(nsIRequest *re
     // We're done uploading.  Let our consumer know that we're done.
     Close();
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-nsFtpState::Available(PRUint32 *result)
+nsFtpState::Available(PRUint64 *result)
 {
     if (mDataStream)
         return mDataStream->Available(result);
 
     return nsBaseContentStream::Available(result);
 }
 
 NS_IMETHODIMP
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.h
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.h
@@ -93,17 +93,17 @@ public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIINPUTSTREAMCALLBACK
     NS_DECL_NSITRANSPORTEVENTSINK
     NS_DECL_NSICACHELISTENER
     NS_DECL_NSIREQUESTOBSERVER
 
     // Override input stream methods:
     NS_IMETHOD CloseWithStatus(nsresult status);
-    NS_IMETHOD Available(PRUint32 *result);
+    NS_IMETHOD Available(PRUint64 *result);
     NS_IMETHOD ReadSegments(nsWriteSegmentFun fun, void *closure,
                             PRUint32 count, PRUint32 *result);
 
     // nsFtpControlConnectionListener methods:
     virtual void OnControlDataAvailable(const char *data, PRUint32 dataLen);
     virtual void OnControlError(nsresult status);
 
     nsFtpState();
--- a/netwerk/protocol/ftp/nsFtpControlConnection.cpp
+++ b/netwerk/protocol/ftp/nsFtpControlConnection.cpp
@@ -29,25 +29,25 @@ extern PRLogModuleInfo* gFTPLog;
 NS_IMPL_ISUPPORTS1(nsFtpControlConnection, nsIInputStreamCallback)
 
 NS_IMETHODIMP
 nsFtpControlConnection::OnInputStreamReady(nsIAsyncInputStream *stream)
 {
     char data[4096];
 
     // Consume data whether we have a listener or not.
+    PRUint64 avail64;
     PRUint32 avail;
-    nsresult rv = stream->Available(&avail);
+    nsresult rv = stream->Available(&avail64);
     if (NS_SUCCEEDED(rv)) {
-        if (avail > sizeof(data))
-            avail = sizeof(data);
+        avail = (PRUint32)NS_MIN(avail64, (PRUint64)sizeof(data));
 
         PRUint32 n;
         rv = stream->Read(data, avail, &n);
-        if (NS_SUCCEEDED(rv) && n != avail)
+        if (NS_SUCCEEDED(rv))
             avail = n;
     }
 
     // It's important that we null out mListener before calling one of its
     // methods as it may call WaitData, which would queue up another read.
 
     nsRefPtr<nsFtpControlConnectionListener> listener;
     listener.swap(mListener);
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -440,43 +440,34 @@ HttpBaseChannel::SetUploadStream(nsIInpu
   // NOTE: for backwards compatibility and for compatibility with old style
   // plugins, |stream| may include headers, specifically Content-Type and
   // Content-Length headers.  in this case, |contentType| and |contentLength|
   // would be unspecified.  this is traditionally the case of a POST request,
   // and so we select POST as the request method if contentType and
   // contentLength are unspecified.
 
   if (stream) {
+    nsCAutoString method;
+    bool hasHeaders;
+
     if (contentType.IsEmpty()) {
-      mUploadStreamHasHeaders = true;
-      mRequestHead.SetMethod(nsHttp::Post); // POST request
+      method = nsHttp::Post;
+      hasHeaders = true;
     } else {
-      if (contentLength < 0) {
-        // Not really kosher to assume Available == total length of
-        // stream, but apparently works for the streams we see here.
-        stream->Available((PRUint32 *) &contentLength);
-        if (contentLength < 0) {
-          NS_ERROR("unable to determine content length");
-          return NS_ERROR_FAILURE;
-        }
-      }
-      // SetRequestHeader propagates headers to chrome if HttpChannelChild 
-      nsCAutoString contentLengthStr;
-      contentLengthStr.AppendInt(PRInt64(contentLength));
-      SetRequestHeader(NS_LITERAL_CSTRING("Content-Length"), contentLengthStr, 
-                       false);
-      SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), contentType, 
-                       false);
-      mUploadStreamHasHeaders = false;
-      mRequestHead.SetMethod(nsHttp::Put); // PUT request
+      method = nsHttp::Put;
+      hasHeaders = false;
     }
-  } else {
-    mUploadStreamHasHeaders = false;
-    mRequestHead.SetMethod(nsHttp::Get); // revert to GET request
+    return ExplicitSetUploadStream(stream, contentType, contentLength,
+                                   method, hasHeaders);
   }
+
+  // if stream is null, ExplicitSetUploadStream returns error.
+  // So we need special case for GET method.
+  mUploadStreamHasHeaders = false;
+  mRequestHead.SetMethod(nsHttp::Get); // revert to GET request
   mUploadStream = stream;
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // HttpBaseChannel::nsIUploadChannel2
 //-----------------------------------------------------------------------------
 
@@ -486,20 +477,18 @@ HttpBaseChannel::ExplicitSetUploadStream
                                        PRInt64 aContentLength,
                                        const nsACString &aMethod,
                                        bool aStreamHasHeaders)
 {
   // Ensure stream is set and method is valid 
   NS_ENSURE_TRUE(aStream, NS_ERROR_FAILURE);
 
   if (aContentLength < 0 && !aStreamHasHeaders) {
-    PRUint32 streamLength;
-    aStream->Available(&streamLength);
-    aContentLength = streamLength;
-    if (aContentLength < 0) {
+    nsresult rv = aStream->Available(reinterpret_cast<PRUint64*>(&aContentLength));
+    if (NS_FAILED(rv) || aContentLength < 0) {
       NS_ERROR("unable to determine content length");
       return NS_ERROR_FAILURE;
     }
   }
 
   nsresult rv = SetRequestMethod(aMethod);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/netwerk/protocol/http/NullHttpTransaction.cpp
+++ b/netwerk/protocol/http/NullHttpTransaction.cpp
@@ -84,17 +84,17 @@ NullHttpTransaction::Status()
 }
 
 PRUint8
 NullHttpTransaction::Caps()
 {
   return mCaps;
 }
 
-PRUint32
+PRUint64
 NullHttpTransaction::Available()
 {
   return 0;
 }
 
 nsresult
 NullHttpTransaction::ReadSegments(nsAHttpSegmentReader *reader,
                                   PRUint32 count, PRUint32 *countRead)
--- a/netwerk/protocol/http/SpdySession2.cpp
+++ b/netwerk/protocol/http/SpdySession2.cpp
@@ -2196,17 +2196,17 @@ SpdySession2::Status()
 
 PRUint8
 SpdySession2::Caps()
 {
   NS_ABORT_IF_FALSE(false, "SpdySession2::Caps()");
   return 0;
 }
 
-PRUint32
+PRUint64
 SpdySession2::Available()
 {
   NS_ABORT_IF_FALSE(false, "SpdySession2::Available()");
   return 0;
 }
 
 nsHttpRequestHead *
 SpdySession2::RequestHead()
--- a/netwerk/protocol/http/SpdySession3.cpp
+++ b/netwerk/protocol/http/SpdySession3.cpp
@@ -2253,17 +2253,17 @@ SpdySession3::Status()
 
 PRUint8
 SpdySession3::Caps()
 {
   NS_ABORT_IF_FALSE(false, "SpdySession3::Caps()");
   return 0;
 }
 
-PRUint32
+PRUint64
 SpdySession3::Available()
 {
   NS_ABORT_IF_FALSE(false, "SpdySession3::Available()");
   return 0;
 }
 
 nsHttpRequestHead *
 SpdySession3::RequestHead()
--- a/netwerk/protocol/http/nsAHttpTransaction.h
+++ b/netwerk/protocol/http/nsAHttpTransaction.h
@@ -45,17 +45,17 @@ public:
                                    nsresult status, PRUint64 progress) = 0;
 
     // called to check the transaction status.
     virtual bool     IsDone() = 0;
     virtual nsresult Status() = 0;
     virtual PRUint8  Caps() = 0;
 
     // called to find out how much request data is available for writing.
-    virtual PRUint32 Available() = 0;
+    virtual PRUint64 Available() = 0;
 
     // called to read request data from the transaction.
     virtual nsresult ReadSegments(nsAHttpSegmentReader *reader,
                                   PRUint32 count, PRUint32 *countRead) = 0;
 
     // called to write response data to the transaction.
     virtual nsresult WriteSegments(nsAHttpSegmentWriter *writer,
                                    PRUint32 count, PRUint32 *countWritten) = 0;
@@ -140,17 +140,17 @@ public:
     nsAHttpConnection *Connection(); \
     void GetSecurityCallbacks(nsIInterfaceRequestor **, \
                               nsIEventTarget **);       \
     void OnTransportStatus(nsITransport* transport, \
                            nsresult status, PRUint64 progress); \
     bool     IsDone(); \
     nsresult Status(); \
     PRUint8  Caps();   \
-    PRUint32 Available(); \
+    PRUint64 Available(); \
     nsresult ReadSegments(nsAHttpSegmentReader *, PRUint32, PRUint32 *); \
     nsresult WriteSegments(nsAHttpSegmentWriter *, PRUint32, PRUint32 *); \
     void     Close(nsresult reason);                                    \
     void     SetSSLConnectFailed();                                     \
     nsHttpRequestHead *RequestHead();                                   \
     PRUint32 Http1xTransactionCount();                                  \
     nsresult TakeSubTransactions(nsTArray<nsRefPtr<nsAHttpTransaction> > &outTransactions); \
     nsresult AddTransaction(nsAHttpTransaction *);                      \
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -557,21 +557,21 @@ nsHttpConnection::CanReuse()
 
     canReuse = canReuse && (IdleTime() < mIdleTimeout) && IsAlive();
 
     // An idle persistent connection should not have data waiting to be read
     // before a request is sent. Data here is likely a 408 timeout response
     // which we would deal with later on through the restart logic, but that
     // path is more expensive than just closing the socket now.
 
-    PRUint32 dataSize;
+    PRUint64 dataSize;
     if (canReuse && mSocketIn && !mUsingSpdyVersion && mHttp1xTransactionCount &&
         NS_SUCCEEDED(mSocketIn->Available(&dataSize)) && dataSize) {
         LOG(("nsHttpConnection::CanReuse %p %s"
-             "Socket not reusable because read data pending (%d) on it.\n",
+             "Socket not reusable because read data pending (%llu) on it.\n",
              this, mConnInfo->Host(), dataSize));
         canReuse = false;
     }
     return canReuse;
 }
 
 bool
 nsHttpConnection::CanDirectlyActivate()
--- a/netwerk/protocol/http/nsHttpPipeline.cpp
+++ b/netwerk/protocol/http/nsHttpPipeline.cpp
@@ -554,20 +554,20 @@ nsHttpPipeline::Caps()
 {
     nsAHttpTransaction *trans = Request(0);
     if (!trans)
         trans = Response(0);
 
     return trans ? trans->Caps() : 0;
 }
 
-PRUint32
+PRUint64
 nsHttpPipeline::Available()
 {
-    PRUint32 result = 0;
+    PRUint64 result = 0;
 
     PRInt32 i, count = mRequestQ.Length();
     for (i=0; i<count; ++i)
         result += Request(i)->Available();
     return result;
 }
 
 NS_METHOD
@@ -592,17 +592,17 @@ nsHttpPipeline::ReadSegments(nsAHttpSegm
     NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
 
     if (mClosed) {
         *countRead = 0;
         return mStatus;
     }
 
     nsresult rv;
-    PRUint32 avail = 0;
+    PRUint64 avail = 0;
     if (mSendBufIn) {
         rv = mSendBufIn->Available(&avail);
         if (NS_FAILED(rv)) return rv;
     }
 
     if (avail == 0) {
         rv = FillSendBuf();
         if (NS_FAILED(rv)) return rv;
@@ -618,17 +618,18 @@ nsHttpPipeline::ReadSegments(nsAHttpSegm
     }
 
     // read no more than what was requested
     if (avail > count)
         avail = count;
 
     mReader = reader;
 
-    rv = mSendBufIn->ReadSegments(ReadFromPipe, this, avail, countRead);
+    // avail is under 4GB, so casting to PRUint32 is safe
+    rv = mSendBufIn->ReadSegments(ReadFromPipe, this, (PRUint32)avail, countRead);
 
     mReader = nullptr;
     return rv;
 }
 
 nsresult
 nsHttpPipeline::WriteSegments(nsAHttpSegmentWriter *writer,
                               PRUint32 count,
@@ -830,31 +831,32 @@ nsHttpPipeline::FillSendBuf()
         rv = NS_NewPipe(getter_AddRefs(mSendBufIn),
                         getter_AddRefs(mSendBufOut),
                         nsIOService::gDefaultSegmentSize,  /* segment size */
                         nsIOService::gDefaultSegmentSize,  /* max size */
                         true, true);
         if (NS_FAILED(rv)) return rv;
     }
 
-    PRUint32 n, avail;
+    PRUint32 n;
+    PRUint64 avail;
     nsAHttpTransaction *trans;
     nsITransport *transport = Transport();
 
     while ((trans = Request(0)) != nullptr) {
         avail = trans->Available();
         if (avail) {
             // if there is already a response in the responseq then this
             // new data comprises a pipeline. Update the transaction in the
             // response queue to reflect that if necessary. We are now sending
             // out a request while we haven't received all responses.
             nsAHttpTransaction *response = Response(0);
             if (response && !response->PipelinePosition())
                 response->SetPipelinePosition(1);
-            rv = trans->ReadSegments(this, avail, &n);
+            rv = trans->ReadSegments(this, (PRUint32)NS_MIN(avail, (PRUint64)PR_UINT32_MAX), &n);
             if (NS_FAILED(rv)) return rv;
             
             if (n == 0) {
                 LOG(("send pipe is full"));
                 break;
             }
 
             mSendingToProgress += n;
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -486,20 +486,20 @@ nsHttpTransaction::Status()
 }
 
 PRUint8
 nsHttpTransaction::Caps()
 { 
     return mCaps;
 }
 
-PRUint32
+PRUint64
 nsHttpTransaction::Available()
 {
-    PRUint32 size;
+    PRUint64 size;
     if (NS_FAILED(mRequestStream->Available(&size)))
         size = 0;
     return size;
 }
 
 NS_METHOD
 nsHttpTransaction::ReadRequestSegment(nsIInputStream *stream,
                                       void *closure,
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -136,17 +136,17 @@ private:
     nsCOMPtr<nsIAsyncInputStream>   mPipeIn;
     nsCOMPtr<nsIAsyncOutputStream>  mPipeOut;
 
     nsCOMPtr<nsISupports>             mChannel;
     nsCOMPtr<nsIHttpActivityObserver> mActivityDistributor;
 
     nsCString                       mReqHeaderBuf;    // flattened request headers
     nsCOMPtr<nsIInputStream>        mRequestStream;
-    PRUint32                        mRequestSize;
+    PRUint64                        mRequestSize;
 
     nsAHttpConnection              *mConnection;      // hard ref
     nsHttpConnectionInfo           *mConnInfo;        // hard ref
     nsHttpRequestHead              *mRequestHead;     // weak ref
     nsHttpResponseHead             *mResponseHead;    // hard ref
 
     nsAHttpSegmentReader           *mReader;
     nsAHttpSegmentWriter           *mWriter;
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -716,17 +716,17 @@ public:
   }
 
   nsresult ConvertStreamToString()
   {
     NS_ABORT_IF_FALSE(mMsgType == kMsgTypeStream, "Not a stream!");
 
 #ifdef DEBUG
     // Make sure we got correct length from Blob
-    PRUint32 bytes;
+    PRUint64 bytes;
     mMsg.pStream->Available(&bytes);
     NS_ASSERTION(bytes == mLength, "Stream length != blob length!");
 #endif
 
     nsAutoPtr<nsCString> temp(new nsCString());
     nsresult rv = NS_ReadInputStreamToString(mMsg.pStream, *temp, mLength);
 
     NS_ENSURE_SUCCESS(rv, rv);
--- a/netwerk/streamconv/converters/nsFTPDirListingConv.cpp
+++ b/netwerk/streamconv/converters/nsFTPDirListingConv.cpp
@@ -82,18 +82,20 @@ nsFTPDirListingConv::OnDataAvailable(nsI
     
     nsresult rv;
 
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     
     PRUint32 read, streamLen;
 
-    rv = inStr->Available(&streamLen);
+    PRUint64 streamLen64;
+    rv = inStr->Available(&streamLen64);
     NS_ENSURE_SUCCESS(rv, rv);
+    streamLen = (PRUint32)NS_MIN(streamLen64, PRUint64(PR_UINT32_MAX - 1));
 
     nsAutoArrayPtr<char> buffer(new char[streamLen + 1]);
     NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
 
     rv = inStr->Read(buffer, streamLen, &read);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // the dir listings are ascii text, null terminate this sucker.
--- a/netwerk/streamconv/test/Converters.cpp
+++ b/netwerk/streamconv/test/Converters.cpp
@@ -73,35 +73,51 @@ TestConverter::AsyncConvertData(const ch
 
     // based on these types, setup internal state to handle the appropriate conversion.
     fromType = aFromType;
     toType = aToType;
 
     return NS_OK; 
 }
 
+static inline PRUint32
+saturated(PRUint64 aValue)
+{
+    return (PRUint32) NS_MIN(aValue, (PRUint64) PR_UINT32_MAX);
+}
+
 // nsIStreamListener method
 /* This method handles asyncronous conversion of data. */
 NS_IMETHODIMP
 TestConverter::OnDataAvailable(nsIRequest* request,
                                nsISupports *ctxt, 
                                nsIInputStream *inStr, 
                                PRUint32 sourceOffset, 
                                PRUint32 count) {
     nsresult rv;
     nsCOMPtr<nsIInputStream> convertedStream;
     // just make a syncronous call to the Convert() method.
     // Anything can happen here, I just happen to be using the sync call to 
     // do the actual conversion.
     rv = Convert(inStr, fromType.get(), toType.get(), ctxt, getter_AddRefs(convertedStream));
     if (NS_FAILED(rv)) return rv;
 
-    PRUint32 len;
+    PRUint64 len = 0;
     convertedStream->Available(&len);
-    return mListener->OnDataAvailable(request, ctxt, convertedStream, sourceOffset, len);
+
+    PRUint64 offset = sourceOffset;
+    while (len > 0) {
+        PRUint32 count = saturated(len);
+        rv = mListener->OnDataAvailable(request, ctxt, convertedStream, saturated(offset), count);
+        if (NS_FAILED(rv)) return rv;
+
+        offset += count;
+        len -= count;
+    }
+    return NS_OK;
 }
 
 // nsIRequestObserver methods
 /* These methods just pass through directly to the mListener */
 NS_IMETHODIMP
 TestConverter::OnStartRequest(nsIRequest* request, nsISupports *ctxt) {
     return mListener->OnStartRequest(request, ctxt);
 }
--- a/netwerk/streamconv/test/TestStreamConv.cpp
+++ b/netwerk/streamconv/test/TestStreamConv.cpp
@@ -57,19 +57,21 @@ public:
 
     EndListener() {};
 
     // nsIStreamListener method
     NS_IMETHOD OnDataAvailable(nsIRequest* request, nsISupports *ctxt, nsIInputStream *inStr, 
                                PRUint32 sourceOffset, PRUint32 count)
     {
         nsresult rv;
-        PRUint32 read, len;
-        rv = inStr->Available(&len);
+        PRUint32 read;
+        PRUint64 len64;
+        rv = inStr->Available(&len64);
         if (NS_FAILED(rv)) return rv;
+        PRUint32 len = (PRUint32)NS_MIN(len64, (PRUint64)(PR_UINT32_MAX - 1));
 
         char *buffer = (char*)nsMemory::Alloc(len + 1);
         if (!buffer) return NS_ERROR_OUT_OF_MEMORY;
 
         rv = inStr->Read(buffer, len, &read);
         buffer[len] = '\0';
         if (NS_SUCCEEDED(rv)) {
             printf("CONTEXT %p: Received %u bytes and the following data: \n %s\n\n",
@@ -90,31 +92,46 @@ public:
 NS_IMPL_ISUPPORTS2(EndListener,
                    nsIStreamListener,
                    nsIRequestObserver)
 
 ////////////////////////////////////////////////////////////////////////
 // EndListener END
 ////////////////////////////////////////////////////////////////////////
 
-
+static PRUint32 
+saturated(PRUint64 aValue)
+{
+    return (PRUint32)NS_MIN(aValue, (PRUint64)PR_UINT32_MAX);
+}
+ 
 nsresult SendData(const char * aData, nsIStreamListener* aListener, nsIRequest* request) {
     nsresult rv;
 
     nsCOMPtr<nsIStringInputStream> dataStream
       (do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv));
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = dataStream->SetData(aData, strlen(aData));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    PRUint32 avail;
+    PRUint64 avail = 0;
     dataStream->Available(&avail);
 
-    return aListener->OnDataAvailable(request, nullptr, dataStream, 0, avail);
+    PRUint64 offset = 0;
+    while (avail > 0) {
+        PRUint32 count = saturated(avail);
+        rv = aListener->OnDataAvailable(request, nullptr, dataStream,
+                                        saturated(offset), count);
+        if (NS_FAILED(rv)) return rv;
+
+        offset += count;
+        avail -= count;
+    }
+    return NS_OK;
 }
 #define SEND_DATA(x) SendData(x, converterListener, request)
 
 static const mozilla::Module::CIDEntry kTestCIDs[] = {
     { &kTestConverterCID, false, NULL, CreateTestConverter },
     { NULL }
 };
 
--- a/parser/xml/src/nsSAXXMLReader.cpp
+++ b/parser/xml/src/nsSAXXMLReader.cpp
@@ -496,33 +496,38 @@ nsSAXXMLReader::ParseFromStream(nsIInput
      before the DTD tag (such as a space before an XML declaration).
    */
   mSystemId.Truncate();
   mPublicId.Truncate();
 
   nsresult status;
   parserChannel->GetStatus(&status);
   
-  PRUint32 offset = 0;
+  PRUint64 offset = 0;
   while (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
-    PRUint32 available;
+    PRUint64 available;
     rv = aStream->Available(&available);
     if (rv == NS_BASE_STREAM_CLOSED) {
       rv = NS_OK;
       available = 0;
     }
     if (NS_FAILED(rv)) {
       parserChannel->Cancel(rv);
       break;
     }
     if (! available)
       break; // blocking input stream has none available when done
 
+    if (available > PR_UINT32_MAX)
+      available = PR_UINT32_MAX;
+
     rv = mListener->OnDataAvailable(parserChannel, nullptr,
-                                    aStream, offset, available);
+                                    aStream,
+                                    (PRUint32)NS_MIN(offset, (PRUint64)PR_UINT32_MAX),
+                                    (PRUint32)available);
     if (NS_SUCCEEDED(rv))
       offset += available;
     else
       parserChannel->Cancel(rv);
     parserChannel->GetStatus(&status);
   }
   rv = mListener->OnStopRequest(parserChannel, nullptr, status);
   mListener = nullptr;
--- a/rdf/base/src/nsRDFXMLDataSource.cpp
+++ b/rdf/base/src/nsRDFXMLDataSource.cpp
@@ -514,31 +514,34 @@ RDFXMLDataSourceImpl::BlockingParse(nsIU
 
         if (obs) {
             obs->OnBeginLoad(this);
         }
     }
 
     rv = aConsumer->OnStartRequest(channel, nullptr);
 
-    PRUint32 offset = 0;
+    PRUint64 offset = 0;
     while (NS_SUCCEEDED(rv)) {
         // Skip ODA if the channel is canceled
         channel->GetStatus(&rv);
         if (NS_FAILED(rv))
             break;
 
-        PRUint32 avail;
+        PRUint64 avail;
         if (NS_FAILED(rv = bufStream->Available(&avail)))
             break; // error
 
         if (avail == 0)
             break; // eof
 
-        rv = aConsumer->OnDataAvailable(channel, nullptr, bufStream, offset, avail);
+        if (avail > PR_UINT32_MAX)
+            avail = PR_UINT32_MAX;
+
+        rv = aConsumer->OnDataAvailable(channel, nullptr, bufStream, (PRUint32)NS_MIN(offset, (PRUint64)PR_UINT32_MAX), (PRUint32)avail);
         if (NS_SUCCEEDED(rv))
             offset += avail;
     }
 
     if (NS_FAILED(rv))
         channel->Cancel(rv);
 
     channel->GetStatus(&rv);
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
@@ -2770,33 +2770,34 @@ nsCryptoHash::Update(const PRUint8 *data
   if (!mInitialized)
     return NS_ERROR_NOT_INITIALIZED;
 
   HASH_Update(mHashContext, data, len);
   return NS_OK; 
 }
 
 NS_IMETHODIMP
-nsCryptoHash::UpdateFromStream(nsIInputStream *data, PRUint32 len)
+nsCryptoHash::UpdateFromStream(nsIInputStream *data, PRUint32 aLen)
 {
   if (!mInitialized)
     return NS_ERROR_NOT_INITIALIZED;
 
   if (!data)
     return NS_ERROR_INVALID_ARG;
 
-  PRUint32 n;
+  PRUint64 n;
   nsresult rv = data->Available(&n);
   if (NS_FAILED(rv))
     return rv;
 
   // if the user has passed PR_UINT32_MAX, then read
   // everything in the stream
 
-  if (len == PR_UINT32_MAX)
+  PRUint64 len = aLen;
+  if (aLen == PR_UINT32_MAX)
     len = n;
 
   // So, if the stream has NO data available for the hash,
   // or if the data available is less then what the caller
   // requested, we can not fulfill the hash update.  In this
   // case, just return NS_ERROR_NOT_AVAILABLE indicating
   // that there is not enough data in the stream to satisify
   // the request.
@@ -2804,17 +2805,17 @@ nsCryptoHash::UpdateFromStream(nsIInputS
   if (n == 0 || n < len)
     return NS_ERROR_NOT_AVAILABLE;
   
   char buffer[NS_CRYPTO_HASH_BUFFER_SIZE];
   PRUint32 read, readLimit;
   
   while(NS_SUCCEEDED(rv) && len>0)
   {
-    readLimit = NS_MIN(PRUint32(NS_CRYPTO_HASH_BUFFER_SIZE), len);
+    readLimit = (PRUint32)NS_MIN<PRUint64>(NS_CRYPTO_HASH_BUFFER_SIZE, len);
     
     rv = data->Read(buffer, readLimit, &read);
     
     if (NS_SUCCEEDED(rv))
       rv = Update((const PRUint8*)buffer, read);
     
     len -= read;
   }
@@ -2970,52 +2971,53 @@ NS_IMETHODIMP nsCryptoHMAC::Update(const
 NS_IMETHODIMP nsCryptoHMAC::UpdateFromStream(nsIInputStream *aStream, PRUint32 aLen)
 {
   if (!mHMACContext)
     return NS_ERROR_NOT_INITIALIZED;
 
   if (!aStream)
     return NS_ERROR_INVALID_ARG;
 
-  PRUint32 n;
+  PRUint64 n;
   nsresult rv = aStream->Available(&n);
   if (NS_FAILED(rv))
     return rv;
 
   // if the user has passed PR_UINT32_MAX, then read
   // everything in the stream
 
+  PRUint64 len = aLen;
   if (aLen == PR_UINT32_MAX)
-    aLen = n;
+    len = n;
 
   // So, if the stream has NO data available for the hash,
   // or if the data available is less then what the caller
   // requested, we can not fulfill the HMAC update.  In this
   // case, just return NS_ERROR_NOT_AVAILABLE indicating
   // that there is not enough data in the stream to satisify
   // the request.
 
-  if (n == 0 || n < aLen)
+  if (n == 0 || n < len)
     return NS_ERROR_NOT_AVAILABLE;
   
   char buffer[NS_CRYPTO_HASH_BUFFER_SIZE];
   PRUint32 read, readLimit;
   
-  while(NS_SUCCEEDED(rv) && aLen > 0)
+  while(NS_SUCCEEDED(rv) && len > 0)
   {
-    readLimit = NS_MIN(PRUint32(NS_CRYPTO_HASH_BUFFER_SIZE), aLen);
+    readLimit = (PRUint32)NS_MIN<PRUint64>(NS_CRYPTO_HASH_BUFFER_SIZE, len);
     
     rv = aStream->Read(buffer, readLimit, &read);
     if (read == 0)
       return NS_BASE_STREAM_CLOSED;
     
     if (NS_SUCCEEDED(rv))
       rv = Update((const PRUint8*)buffer, read);
     
-    aLen -= read;
+    len -= read;
   }
   
   return rv;
 }
 
 /* ACString finish (in bool aASCII); */
 NS_IMETHODIMP nsCryptoHMAC::Finish(bool aASCII, nsACString & _retval)
 {
--- a/startupcache/StartupCacheUtils.cpp
+++ b/startupcache/StartupCacheUtils.cpp
@@ -74,21 +74,24 @@ NS_EXPORT nsresult
 NewBufferFromStorageStream(nsIStorageStream *storageStream, 
                            char** buffer, PRUint32* len) 
 {
   nsresult rv;
   nsCOMPtr<nsIInputStream> inputStream;
   rv = storageStream->NewInputStream(0, getter_AddRefs(inputStream));
   NS_ENSURE_SUCCESS(rv, rv);
   
-  PRUint32 avail, read;
-  rv = inputStream->Available(&avail);
+  PRUint64 avail64;
+  rv = inputStream->Available(&avail64);
   NS_ENSURE_SUCCESS(rv, rv);
-  
+  NS_ENSURE_TRUE(avail64 <= PR_UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
+
+  PRUint32 avail = (PRUint32)avail64;
   nsAutoArrayPtr<char> temp (new char[avail]);
+  PRUint32 read;
   rv = inputStream->Read(temp, avail, &read);
   if (NS_SUCCEEDED(rv) && avail != read)
     rv = NS_ERROR_UNEXPECTED;
   
   if (NS_FAILED(rv)) {
     return rv;
   }
   
--- a/toolkit/components/places/nsFaviconService.cpp
+++ b/toolkit/components/places/nsFaviconService.cpp
@@ -594,21 +594,22 @@ nsFaviconService::ReplaceFaviconDataFrom
   rv = protocolHandler->NewChannel(dataURI, getter_AddRefs(channel));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Blocking stream is OK for data URIs.
   nsCOMPtr<nsIInputStream> stream;
   rv = channel->Open(getter_AddRefs(stream));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRUint32 available;
-  rv = stream->Available(&available);
+  PRUint64 available64;
+  rv = stream->Available(&available64);
   NS_ENSURE_SUCCESS(rv, rv);
-  if (available == 0)
-    return NS_ERROR_FAILURE;
+  if (available64 == 0 || available64 > PR_UINT32_MAX / sizeof(PRUint8))
+    return NS_ERROR_FILE_TOO_BIG;
+  PRUint32 available = (PRUint32)available64;
 
   // Read all the decoded data.
   PRUint8* buffer = static_cast<PRUint8*>
                                (nsMemory::Alloc(sizeof(PRUint8) * available));
   if (!buffer)
     return NS_ERROR_OUT_OF_MEMORY;
   PRUint32 numRead;
   rv = stream->Read(TO_CHARBUFFER(buffer), available, &numRead);
@@ -656,21 +657,22 @@ nsFaviconService::SetFaviconDataFromData
   rv = protocolHandler->NewChannel(dataURI, getter_AddRefs(channel));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // blocking stream is OK for data URIs
   nsCOMPtr<nsIInputStream> stream;
   rv = channel->Open(getter_AddRefs(stream));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRUint32 available;
-  rv = stream->Available(&available);
+  PRUint64 available64;
+  rv = stream->Available(&available64);
   NS_ENSURE_SUCCESS(rv, rv);
-  if (available == 0)
+  if (available64 == 0 || available64 > PR_UINT32_MAX / sizeof(PRUint8))
     return NS_ERROR_FAILURE;
+  PRUint32 available = (PRUint32)available64;
 
   // read all the decoded data
   PRUint8* buffer = static_cast<PRUint8*>
                                (nsMemory::Alloc(sizeof(PRUint8) * available));
   if (!buffer)
     return NS_ERROR_OUT_OF_MEMORY;
   PRUint32 numRead;
   rv = stream->Read(reinterpret_cast<char*>(buffer), available, &numRead);
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -585,19 +585,22 @@ NS_IMETHODIMP AsyncWriteIconToDisk::Run(
   rv = icoFile->InitWithPath(mIconPath);
 
   // Setup the output stream for the ICO file on disk
   nsCOMPtr<nsIOutputStream> outputStream;
   rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), icoFile);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Obtain the ICO buffer size from the re-encoded ICO stream
-  PRUint32 bufSize;
-  rv = iconStream->Available(&bufSize);
+  PRUint64 bufSize64;
+  rv = iconStream->Available(&bufSize64);
   NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_TRUE(bufSize64 <= PR_UINT32_MAX, NS_ERROR_FILE_TOO_BIG);
+
+  PRUint32 bufSize = (PRUint32)bufSize64;
 
   // Setup a buffered output stream from the stream object
   // so that we can simply use WriteFrom with the stream object
   nsCOMPtr<nsIOutputStream> bufferedOutputStream;
   rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
                                   outputStream, bufSize);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/xpcom/io/Base64.cpp
+++ b/xpcom/io/Base64.cpp
@@ -154,24 +154,28 @@ EncodeInputStream_Encoder(nsIInputStream
 template <typename T>
 nsresult
 EncodeInputStream(nsIInputStream *aInputStream, 
                   T &aDest,
                   PRUint32 aCount,
                   PRUint32 aOffset)
 {
   nsresult rv;
+  PRUint64 count64 = aCount;
 
   if (!aCount) {
-    rv = aInputStream->Available(&aCount);
+    rv = aInputStream->Available(&count64);
     NS_ENSURE_SUCCESS(rv, rv);
+    // if count64 is over 4GB, it will be failed at the below condition,
+    // then will return NS_ERROR_OUT_OF_MEMORY
+    aCount = (PRUint32)count64;
   }
 
   PRUint64 countlong =
-    (PRUint64(aCount) + 2) / 3 * 4; // +2 due to integer math.
+    (count64 + 2) / 3 * 4; // +2 due to integer math.
   if (countlong + aOffset > PR_UINT32_MAX)
     return NS_ERROR_OUT_OF_MEMORY;
 
   PRUint32 count = PRUint32(countlong);
 
   aDest.SetLength(count + aOffset);
   if (aDest.Length() != count + aOffset)
     return NS_ERROR_OUT_OF_MEMORY;
--- a/xpcom/io/nsBinaryStream.cpp
+++ b/xpcom/io/nsBinaryStream.cpp
@@ -299,17 +299,17 @@ nsBinaryOutputStream::PutBuffer(char* aB
 {
     if (mBufferAccess)
         mBufferAccess->PutBuffer(aBuffer, aLength);
 }
 
 NS_IMPL_ISUPPORTS3(nsBinaryInputStream, nsIObjectInputStream, nsIBinaryInputStream, nsIInputStream)
 
 NS_IMETHODIMP
-nsBinaryInputStream::Available(PRUint32* aResult)
+nsBinaryInputStream::Available(PRUint64* aResult)
 {
     NS_ENSURE_STATE(mInputStream);
     return mInputStream->Available(aResult);
 }
 
 NS_IMETHODIMP
 nsBinaryInputStream::Read(char* aBuffer, PRUint32 aCount, PRUint32 *aNumRead)
 {
--- a/xpcom/io/nsIInputStream.idl
+++ b/xpcom/io/nsIInputStream.idl
@@ -51,17 +51,17 @@ native nsWriteSegmentFun(nsWriteSegmentF
  * Close, Available, Read, or ReadSegments.  A non-blocking input stream, on
  * the other hand, must not block the calling thread of execution.
  *
  * NOTE: blocking input streams are often read on a background thread to avoid
  * locking up the main application thread.  For this reason, it is generally
  * the case that a blocking input stream should be implemented using thread-
  * safe AddRef and Release.
  */
-[scriptable, uuid(fa9c7f6c-61b3-11d4-9877-00c04fa0cf4a)]
+[scriptable, uuid(53cdbc97-c2d7-4e30-b2c3-45b2ee79db18)]
 interface nsIInputStream : nsISupports
 {
     /** 
      * Close the stream.  This method causes subsequent calls to Read and
      * ReadSegments to return 0 bytes read to indicate end-of-file.  Any
      * subsequent calls to Available should throw NS_BASE_STREAM_CLOSED.
      */
     void close();
@@ -75,24 +75,23 @@ interface nsIInputStream : nsISupports
      * In addition to the number of bytes available in the stream, this method
      * also informs the caller of the current status of the stream.  A stream
      * that is closed will throw an exception when this method is called.  That
      * enables the caller to know the condition of the stream before attempting
      * to read from it.  If a stream is at end-of-file, but not closed, then
      * this method returns 0 bytes available.  (Note: some nsIInputStream
      * implementations automatically close when eof is reached; some do not).
      *
-     * @return number of bytes currently available in the stream, or
-     *   PR_UINT32_MAX if the size of the stream exceeds PR_UINT32_MAX.
+     * @return number of bytes currently available in the stream.
      *
      * @throws NS_BASE_STREAM_CLOSED if the stream is closed normally.
      * @throws <other-error> if the stream is closed due to some error
      *   condition
      */
-    unsigned long available();
+    unsigned long long available();
 
     /** 
      * Read data from the stream.
      *
      * @param aBuf the buffer into which the data is to be read
      * @param aCount the maximum number of bytes to be read
      *
      * @return number of bytes read (may be less than aCount).
--- a/xpcom/io/nsIScriptableInputStream.idl
+++ b/xpcom/io/nsIScriptableInputStream.idl
@@ -6,17 +6,17 @@
 #include "nsISupports.idl"
 
 interface nsIInputStream;
 
 /**
  * nsIScriptableInputStream provides scriptable access to an nsIInputStream
  * instance.
  */
-[scriptable, uuid(e546afd6-1248-4deb-8940-4b000b618a58)]
+[scriptable, uuid(3fce9015-472a-4080-ac3e-cd875dbe361e)]
 interface nsIScriptableInputStream : nsISupports
 { 
     /** 
      * Closes the stream. 
      */
     void close();
 
     /**
@@ -28,17 +28,17 @@ interface nsIScriptableInputStream : nsI
 
     /**
      * Return the number of bytes currently available in the stream 
      *
      * @return the number of bytes 
      *
      * @throws NS_BASE_STREAM_CLOSED if called after the stream has been closed
      */ 
-    unsigned long available(); 
+    unsigned long long available(); 
 
     /**
      * Read data from the stream.
      *
      * WARNING: If the data contains a null byte, then this method will return
      * a truncated string.
      *
      * @param aCount the maximum number of bytes to read 
--- a/xpcom/io/nsInputStreamTee.cpp
+++ b/xpcom/io/nsInputStreamTee.cpp
@@ -207,17 +207,17 @@ nsInputStreamTee::Close()
     NS_ENSURE_TRUE(mSource, NS_ERROR_NOT_INITIALIZED);
     nsresult rv = mSource->Close();
     mSource = 0;
     mSink = 0;
     return rv;
 }
 
 NS_IMETHODIMP
-nsInputStreamTee::Available(PRUint32 *avail)
+nsInputStreamTee::Available(PRUint64 *avail)
 {
     NS_ENSURE_TRUE(mSource, NS_ERROR_NOT_INITIALIZED);
     return mSource->Available(avail);
 }
 
 NS_IMETHODIMP
 nsInputStreamTee::Read(char *buf, PRUint32 count, PRUint32 *bytesRead)
 {
--- a/xpcom/io/nsMultiplexInputStream.cpp
+++ b/xpcom/io/nsMultiplexInputStream.cpp
@@ -143,29 +143,29 @@ nsMultiplexInputStream::Close()
         nsresult rv2 = mStreams[i]->Close();
         // We still want to close all streams, but we should return an error
         if (NS_FAILED(rv2))
             rv = rv2;
     }
     return rv;
 }
 
-/* unsigned long available (); */
+/* unsigned long long available (); */
 NS_IMETHODIMP
-nsMultiplexInputStream::Available(PRUint32 *_retval)
+nsMultiplexInputStream::Available(PRUint64 *_retval)
 {
     if (NS_FAILED(mStatus))
         return mStatus;
 
     nsresult rv;
-    PRUint32 avail = 0;
+    PRUint64 avail = 0;
 
     PRUint32 len = mStreams.Count();
     for (PRUint32 i = mCurrentStream; i < len; i++) {
-        PRUint32 streamAvail;
+        PRUint64 streamAvail;
         rv = mStreams[i]->Available(&streamAvail);
         NS_ENSURE_SUCCESS(rv, rv);
         avail += streamAvail;
     }
     *_retval = avail;
     return NS_OK;
 }
 
--- a/xpcom/io/nsPipe3.cpp
+++ b/xpcom/io/nsPipe3.cpp
@@ -699,25 +699,26 @@ nsPipeInputStream::CloseWithStatus(nsres
 
 NS_IMETHODIMP
 nsPipeInputStream::Close()
 {
     return CloseWithStatus(NS_BASE_STREAM_CLOSED);
 }
 
 NS_IMETHODIMP
-nsPipeInputStream::Available(PRUint32 *result)
+nsPipeInputStream::Available(PRUint64 *result)
 {
+    // nsPipeInputStream supports under 4GB stream only
     ReentrantMonitorAutoEnter mon(mPipe->mReentrantMonitor);
 
     // return error if pipe closed
     if (!mAvailable && NS_FAILED(mPipe->mStatus))
         return mPipe->mStatus;
 
-    *result = mAvailable;
+    *result = (PRUint64)mAvailable;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPipeInputStream::ReadSegments(nsWriteSegmentFun writer, 
                                 void *closure,  
                                 PRUint32 count,
                                 PRUint32 *readCount)
--- a/xpcom/io/nsScriptableInputStream.cpp
+++ b/xpcom/io/nsScriptableInputStream.cpp
@@ -19,34 +19,34 @@ nsScriptableInputStream::Close(void) {
 NS_IMETHODIMP
 nsScriptableInputStream::Init(nsIInputStream *aInputStream) {
     if (!aInputStream) return NS_ERROR_NULL_POINTER;
     mInputStream = aInputStream;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsScriptableInputStream::Available(PRUint32 *_retval) {
+nsScriptableInputStream::Available(PRUint64 *_retval) {
     if (!mInputStream) return NS_ERROR_NOT_INITIALIZED;
     return mInputStream->Available(_retval);
 }
 
 NS_IMETHODIMP
 nsScriptableInputStream::Read(PRUint32 aCount, char **_retval) {
     nsresult rv = NS_OK;
-    PRUint32 count = 0;
+    PRUint64 count64 = 0;
     char *buffer = nullptr;
 
     if (!mInputStream) return NS_ERROR_NOT_INITIALIZED;
 
-    rv = mInputStream->Available(&count);
+    rv = mInputStream->Available(&count64);
     if (NS_FAILED(rv)) return rv;
 
     // bug716556 - Ensure count+1 doesn't overflow
-    count = NS_MIN(NS_MIN(count, aCount), PR_UINT32_MAX - 1);
+    PRUint32 count = NS_MIN((PRUint32)NS_MIN<PRUint64>(count64, aCount), PR_UINT32_MAX - 1);
     buffer = (char*)nsMemory::Alloc(count+1); // make room for '\0'
     if (!buffer) return NS_ERROR_OUT_OF_MEMORY;
 
     PRUint32 amtRead = 0;
     rv = mInputStream->Read(buffer, count, &amtRead);
     if (NS_FAILED(rv)) {
         nsMemory::Free(buffer);
         return rv;
--- a/xpcom/io/nsStorageStream.cpp
+++ b/xpcom/io/nsStorageStream.cpp
@@ -368,17 +368,17 @@ nsStorageStream::NewInputStream(PRInt32 
 NS_IMETHODIMP
 nsStorageInputStream::Close()
 {
     mStatus = NS_BASE_STREAM_CLOSED;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsStorageInputStream::Available(PRUint32 *aAvailable)
+nsStorageInputStream::Available(PRUint64 *aAvailable)
 {
     if (NS_FAILED(mStatus))
         return mStatus;
 
     *aAvailable = mStorageStream->mLogicalLength - mLogicalCursor;
     return NS_OK;
 }
 
--- a/xpcom/io/nsStreamUtils.cpp
+++ b/xpcom/io/nsStreamUtils.cpp
@@ -606,30 +606,33 @@ NS_CancelAsyncCopy(nsISupports *aCopierC
 
 nsresult
 NS_ConsumeStream(nsIInputStream *stream, PRUint32 maxCount, nsACString &result)
 {
     nsresult rv = NS_OK;
     result.Truncate();
 
     while (maxCount) {
-        PRUint32 avail;
-        rv = stream->Available(&avail);
+        PRUint64 avail64;
+        rv = stream->Available(&avail64);
         if (NS_FAILED(rv)) {
             if (rv == NS_BASE_STREAM_CLOSED)
                 rv = NS_OK;
             break;
         }
-        if (avail == 0)
+        if (avail64 == 0)
             break;
-        if (avail > maxCount)
-            avail = maxCount;
+
+        PRUint32 avail = (PRUint32)NS_MIN<PRUint64>(avail64, maxCount);
 
         // resize result buffer
         PRUint32 length = result.Length();
+        if (avail > PR_UINT32_MAX - length)
+            return NS_ERROR_FILE_TOO_BIG;
+        
         result.SetLength(length + avail);
         if (result.Length() != (length + avail))
             return NS_ERROR_OUT_OF_MEMORY;
         char *buf = result.BeginWriting() + length;
         
         PRUint32 n;
         rv = stream->Read(buf, avail, &n);
         if (NS_FAILED(rv))
--- a/xpcom/io/nsStringStream.cpp
+++ b/xpcom/io/nsStringStream.cpp
@@ -173,17 +173,17 @@ nsStringInputStream::ShareData(const cha
 NS_IMETHODIMP
 nsStringInputStream::Close()
 {
     Clear();
     return NS_OK;
 }
     
 NS_IMETHODIMP
-nsStringInputStream::Available(PRUint32 *aLength)
+nsStringInputStream::Available(PRUint64 *aLength)
 {
     NS_ASSERTION(aLength, "null ptr");
 
     if (Closed())
         return NS_BASE_STREAM_CLOSED;
 
     *aLength = LengthRemaining();
     return NS_OK;
--- a/xpcom/tests/TestBase64.cpp
+++ b/xpcom/tests/TestBase64.cpp
@@ -172,17 +172,17 @@ NS_IMPL_ISUPPORTS1(FakeInputStream, nsII
 NS_IMETHODIMP
 FakeInputStream::Close()
 {
   mClosed = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FakeInputStream::Available(PRUint32* aAvailable)
+FakeInputStream::Available(PRUint64* aAvailable)
 {
   *aAvailable = 0;
 
   if (mClosed)
     return NS_BASE_STREAM_CLOSED;
 
   const Chunk* chunk = mChunk;
   while (chunk->mLength) {