--- 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) {