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 107626 14e988e17b792ef5f50feb9aa96dbf9d71052215
parent 107625 7f3d9cf9b3a1d17d6c0de62450408466fd7123f4
child 107627 1022af7974c986510eeaae7de4c85cb220fd7687
push id1490
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 18:29:50 +0000
treeherdermozilla-beta@f335e7dacdc1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershbambas, bsmedberg, jdrew, sicking
bugs215450
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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) {