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

This commit is contained in:
Honza Bambas 2012-08-10 22:44:11 -04:00
parent 66e7c87620
commit 541453729c
83 changed files with 363 additions and 241 deletions

View File

@ -808,9 +808,13 @@ nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
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;
}

View File

@ -352,9 +352,9 @@ nsSyncLoadService::PushSyncStreamToListener(nsIInputStream* aIn,
// 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) {
@ -364,8 +364,12 @@ nsSyncLoadService::PushSyncStreamToListener(nsIInputStream* aIn,
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;
}

View File

@ -2962,7 +2962,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
}
mUploadComplete = false;
PRUint32 uploadTotal = 0;
PRUint64 uploadTotal = 0;
postDataStream->Available(&uploadTotal);
mUploadTotal = uploadTotal;

View File

@ -359,11 +359,12 @@ nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
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
@ -398,17 +399,18 @@ nsHTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
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;

View File

@ -1053,13 +1053,13 @@ nsresult FileMediaResource::Open(nsIStreamListener** aStreamListener)
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);

View File

@ -646,8 +646,17 @@ nsXULPrototypeCache::BeginCaching(nsIURI* aURI)
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];

View File

@ -3897,11 +3897,13 @@ ReadSourceFromFilename(JSContext *cx, const char *filename, jschar **src, PRUint
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]);

View File

@ -158,7 +158,7 @@ DeviceStorageFile::Write(nsIInputStream* aInputStream)
return rv;
}
PRUint32 bufSize;
PRUint64 bufSize = 0;
aInputStream->Available(&bufSize);
nsCOMPtr<nsIOutputStream> outputStream;
@ -177,12 +177,20 @@ DeviceStorageFile::Write(nsIInputStream* aInputStream)
return NS_ERROR_FAILURE;
}
rv = NS_OK;
while (bufSize) {
PRUint32 wrote;
bufferedOutputStream->WriteFrom(aInputStream, bufSize, &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;
}

View File

@ -169,7 +169,7 @@ ArchiveInputStream::Close()
}
NS_IMETHODIMP
ArchiveInputStream::Available(PRUint32* _retval)
ArchiveInputStream::Available(PRUint64* _retval)
{
*_retval = mLength - mZs.total_out - mStart;
return NS_OK;

View File

@ -139,7 +139,7 @@ FileInputStreamWrapper::Close()
}
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

View File

@ -114,7 +114,7 @@ FileStream::Close()
}
NS_IMETHODIMP
FileStream::Available(PRUint32* aResult)
FileStream::Available(PRUint64* aResult)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -48,7 +48,7 @@ public:
Close();
NS_IMETHOD
Available(PRUint32* _retval);
Available(PRUint64* _retval);
NS_IMETHOD
Read(char* aBuf, PRUint32 aCount, PRUint32* _retval);

View File

@ -84,7 +84,7 @@ public:
}
NS_IMETHOD
Available(PRUint32* aAvailable) MOZ_OVERRIDE
Available(PRUint64* aAvailable) MOZ_OVERRIDE
{
// See large comment in FileInputStreamWrapper::Available.
if (NS_IsMainThread()) {

View File

@ -438,9 +438,9 @@ nsJSON::DecodeInternal(JSContext* cx,
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;
@ -453,8 +453,13 @@ nsJSON::DecodeInternal(JSContext* cx,
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;

View File

@ -145,7 +145,7 @@ class nsGIOInputStream : public nsIInputStream
, mChannel(nullptr)
, mHandle(nullptr)
, mStream(nullptr)
, mBytesRemaining(PR_UINT32_MAX)
, mBytesRemaining(PR_UINT64_MAX)
, mStatus(NS_OK)
, mDirList(nullptr)
, mDirListPtr(nullptr)
@ -634,16 +634,11 @@ nsGIOInputStream::Close()
* @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;
return NS_OK;

View File

@ -319,7 +319,7 @@ class nsGnomeVFSInputStream MOZ_FINAL : public nsIInputStream
: mSpec(uriSpec)
, mChannel(nullptr)
, mHandle(nullptr)
, mBytesRemaining(PR_UINT32_MAX)
, mBytesRemaining(PR_UINT64_MAX)
, mStatus(NS_OK)
, mDirList(nullptr)
, mDirListPtr(nullptr)
@ -355,7 +355,7 @@ class nsGnomeVFSInputStream MOZ_FINAL : public nsIInputStream
nsCString mSpec;
nsIChannel *mChannel; // manually refcounted
GnomeVFSHandle *mHandle;
PRUint32 mBytesRemaining;
PRUint64 mBytesRemaining;
nsresult mStatus;
GList *mDirList;
GList *mDirListPtr;
@ -429,13 +429,14 @@ nsGnomeVFSInputStream::DoOpen()
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
{
@ -478,6 +479,7 @@ nsGnomeVFSInputStream::DoRead(char *aBuf, PRUint32 aCount, PRUint32 *aCountRead)
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;
}
@ -668,7 +670,7 @@ nsGnomeVFSInputStream::Close()
}
NS_IMETHODIMP
nsGnomeVFSInputStream::Available(PRUint32 *aResult)
nsGnomeVFSInputStream::Available(PRUint64 *aResult)
{
if (NS_FAILED(mStatus))
return mStatus;

View File

@ -278,14 +278,21 @@ nsresult nsReadConfig::openAndEvaluateJSFile(const char *aFileName, PRInt32 obsc
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) {

View File

@ -749,11 +749,16 @@ gfxASurface::WriteAsPNG_internal(FILE* aFile, bool aBinary)
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;

View File

@ -321,7 +321,7 @@ NS_IMETHODIMP nsBMPEncoder::Close()
}
// 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;

View File

@ -334,7 +334,7 @@ NS_IMETHODIMP nsICOEncoder::Close()
}
// 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;

View File

@ -236,7 +236,7 @@ NS_IMETHODIMP nsJPEGEncoder::Close()
}
/* unsigned long available (); */
NS_IMETHODIMP nsJPEGEncoder::Available(PRUint32 *_retval)
NS_IMETHODIMP nsJPEGEncoder::Available(PRUint64 *_retval)
{
if (!mImageBuffer)
return NS_BASE_STREAM_CLOSED;

View File

@ -492,7 +492,7 @@ NS_IMETHODIMP nsPNGEncoder::Close()
}
/* unsigned long available (); */
NS_IMETHODIMP nsPNGEncoder::Available(PRUint32 *_retval)
NS_IMETHODIMP nsPNGEncoder::Available(PRUint64 *_retval)
{
if (!mImageBuffer)
return NS_BASE_STREAM_CLOSED;

View File

@ -74,16 +74,17 @@ NS_IMETHODIMP imgTools::DecodeImageData(nsIInputStream* aInStr,
}
// 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!");

View File

@ -855,12 +855,15 @@ mozJSComponentLoader::GlobalForLocation(nsIFile *aComponentFile,
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]);

View File

@ -8143,8 +8143,13 @@ DumpToPNG(nsIPresShell* shell, nsAString& name) {
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);

View File

@ -873,11 +873,16 @@ nsUserFontSet::SyncLoadFontData(gfxProxyFontEntry *aFontToLoad,
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));

View File

@ -422,11 +422,11 @@ nsJAR::LoadEntry(const nsACString &aFilename, char** aBuf, PRUint32* aBufLen)
//-- 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;

View File

@ -132,9 +132,12 @@ nsJARInputThunk::EnsureJarStream()
}
// 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;
}
@ -148,7 +151,7 @@ nsJARInputThunk::Close()
}
NS_IMETHODIMP
nsJARInputThunk::Available(PRUint32 *avail)
nsJARInputThunk::Available(PRUint64 *avail)
{
nsresult rv = EnsureJarStream();
if (NS_FAILED(rv)) return rv;

View File

@ -146,7 +146,7 @@ nsJARInputStream::InitDirectory(nsJAR* aJar,
}
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.

View File

@ -450,7 +450,8 @@ ReadExtensionPrefs(nsIFile *aFile)
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);
@ -759,11 +760,13 @@ static nsresult openPrefFile(nsIFile* 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;

View File

@ -639,7 +639,7 @@ NS_ImplementChannelOpen(nsIChannel *channel,
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)) {

View File

@ -55,7 +55,7 @@ nsBaseContentStream::Close()
}
NS_IMETHODIMP
nsBaseContentStream::Available(PRUint32 *result)
nsBaseContentStream::Available(PRUint64 *result)
{
*result = 0;
return mStatus;

View File

@ -297,7 +297,7 @@ nsBufferedInputStream::Close()
}
NS_IMETHODIMP
nsBufferedInputStream::Available(PRUint32 *result)
nsBufferedInputStream::Available(PRUint64 *result)
{
nsresult rv = NS_OK;
*result = 0;

View File

@ -200,7 +200,7 @@ nsDirectoryIndexStream::Close()
}
NS_IMETHODIMP
nsDirectoryIndexStream::Available(PRUint32* aLength)
nsDirectoryIndexStream::Available(PRUint64* aLength)
{
if (NS_FAILED(mStatus))
return mStatus;

View File

@ -134,7 +134,7 @@ nsFileStreamBase::Close()
}
nsresult
nsFileStreamBase::Available(PRUint32* aResult)
nsFileStreamBase::Available(PRUint64* aResult)
{
nsresult rv = DoPendingOpen();
NS_ENSURE_SUCCESS(rv, rv);
@ -151,7 +151,7 @@ nsFileStreamBase::Available(PRUint32* aResult)
}
// If available is greater than 4GB, return 4GB
*aResult = avail > PR_UINT32_MAX ? PR_UINT32_MAX : (PRUint32)avail;
*aResult = (PRUint64)avail;
return NS_OK;
}
@ -573,9 +573,9 @@ nsPartialFileInputStream::Tell(PRInt64 *aResult)
}
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);
@ -586,7 +586,7 @@ nsPartialFileInputStream::Available(PRUint32* aResult)
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;

View File

@ -34,7 +34,7 @@ public:
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);
@ -111,7 +111,7 @@ public:
NS_DECL_NSIIPCSERIALIZABLE
NS_IMETHOD Close();
NS_IMETHOD Available(PRUint32* _retval)
NS_IMETHOD Available(PRUint64* _retval)
{
return nsFileStreamBase::Available(_retval);
}
@ -182,7 +182,7 @@ public:
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);
@ -190,8 +190,8 @@ public:
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;

View File

@ -19,7 +19,7 @@ nsInputStreamChannel::OpenContentStream(bool async, nsIInputStream **result,
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

View File

@ -101,10 +101,11 @@ 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,
@ -407,7 +408,7 @@ nsInputStreamPump::OnStateStart()
// 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;
@ -435,9 +436,9 @@ nsInputStreamPump::OnStateTransfer()
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;
@ -445,8 +446,8 @@ nsInputStreamPump::OnStateTransfer()
}
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
@ -478,12 +479,15 @@ nsInputStreamPump::OnStateTransfer()
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)) {
@ -493,7 +497,7 @@ nsInputStreamPump::OnStateTransfer()
// 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) {
@ -509,7 +513,7 @@ nsInputStreamPump::OnStateTransfer()
}
}
else
mStreamOffset += avail; // assume ODA behaved well
mStreamOffset += odaAvail; // assume ODA behaved well
}
}
}

View File

@ -170,12 +170,12 @@ void nsMIMEInputStream::InitStreams()
// 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 {
@ -245,7 +245,7 @@ nsMIMEInputStream::ReadSegCb(nsIInputStream* aIn, void* aClosure,
// 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); }

View File

@ -41,9 +41,9 @@ nsPreloadedStream::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))

View File

@ -249,7 +249,7 @@ nsSocketInputStream::Close()
}
NS_IMETHODIMP
nsSocketInputStream::Available(PRUint32 *avail)
nsSocketInputStream::Available(PRUint64 *avail)
{
SOCKET_LOG(("nsSocketInputStream::Available [this=%x]\n", this));

View File

@ -163,7 +163,7 @@ nsInputStreamTransport::Close()
}
NS_IMETHODIMP
nsInputStreamTransport::Available(PRUint32 *result)
nsInputStreamTransport::Available(PRUint64 *result)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -118,7 +118,7 @@ nsSyncStreamListener::Close()
}
NS_IMETHODIMP
nsSyncStreamListener::Available(PRUint32 *result)
nsSyncStreamListener::Available(PRUint64 *result)
{
if (NS_FAILED(mStatus))
return mStatus;
@ -142,11 +142,11 @@ nsSyncStreamListener::Read(char *buf,
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;
}
@ -162,11 +162,11 @@ nsSyncStreamListener::ReadSegments(nsWriteSegmentFun writer,
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;
}

View File

@ -562,7 +562,7 @@ nsInputStreamWrapper::Close()
}
nsresult nsCacheEntryDescriptor::
nsInputStreamWrapper::Available(PRUint32 *avail)
nsInputStreamWrapper::Available(PRUint64 *avail)
{
nsresult rv = EnsureInit();
if (NS_FAILED(rv)) return rv;

View File

@ -93,7 +93,7 @@ nsDiskCacheInputStream::Close()
NS_IMETHODIMP
nsDiskCacheInputStream::Available(PRUint32 * bytesAvailable)
nsDiskCacheInputStream::Available(PRUint64 * bytesAvailable)
{
if (mClosed) return NS_BASE_STREAM_CLOSED;
if (mStreamEnd < mPos) return NS_ERROR_UNEXPECTED;

View File

@ -178,12 +178,15 @@ struct ParamTraits<InputStream>
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!");
}

View File

@ -102,7 +102,7 @@ void AndroidCameraInputStream::ReceiveFrame(char* frame, PRUint32 length) {
}
NS_IMETHODIMP
AndroidCameraInputStream::Available(PRUint32 *aAvailable)
AndroidCameraInputStream::Available(PRUint64 *aAvailable)
{
mozilla::ReentrantMonitorAutoEnter autoMonitor(mMonitor);

View File

@ -393,7 +393,7 @@ GonkCameraInputStream::ReceiveFrame(char* frame, PRUint32 length) {
}
NS_IMETHODIMP
GonkCameraInputStream::Available(PRUint32 *aAvailable)
GonkCameraInputStream::Available(PRUint64 *aAvailable)
{
ReentrantMonitorAutoEnter enter(mMonitor);

View File

@ -422,10 +422,11 @@ nsFileChannel::SetUploadStream(nsIInputStream *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;
if (avail < PR_INT64_MAX)
mUploadLength = avail;
}
} else {

View File

@ -2099,7 +2099,7 @@ nsFtpState::OnStopRequest(nsIRequest *request, nsISupports *context,
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsFtpState::Available(PRUint32 *result)
nsFtpState::Available(PRUint64 *result)
{
if (mDataStream)
return mDataStream->Available(result);

View File

@ -98,7 +98,7 @@ public:
// 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);

View File

@ -34,15 +34,15 @@ 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;
}

View File

@ -445,33 +445,24 @@ HttpBaseChannel::SetUploadStream(nsIInputStream *stream,
// 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;
method = nsHttp::Put;
hasHeaders = false;
}
return ExplicitSetUploadStream(stream, contentType, contentLength,
method, hasHeaders);
}
// 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
}
} else {
// 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;
}
@ -491,10 +482,8 @@ HttpBaseChannel::ExplicitSetUploadStream(nsIInputStream *aStream,
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;
}

View File

@ -89,7 +89,7 @@ NullHttpTransaction::Caps()
return mCaps;
}
PRUint32
PRUint64
NullHttpTransaction::Available()
{
return 0;

View File

@ -2201,7 +2201,7 @@ SpdySession2::Caps()
return 0;
}
PRUint32
PRUint64
SpdySession2::Available()
{
NS_ABORT_IF_FALSE(false, "SpdySession2::Available()");

View File

@ -2258,7 +2258,7 @@ SpdySession3::Caps()
return 0;
}
PRUint32
PRUint64
SpdySession3::Available()
{
NS_ABORT_IF_FALSE(false, "SpdySession3::Available()");

View File

@ -50,7 +50,7 @@ public:
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,
@ -145,7 +145,7 @@ public:
bool IsDone(); \
nsresult Status(); \
PRUint8 Caps(); \
PRUint32 Available(); \
PRUint64 Available(); \
nsresult ReadSegments(nsAHttpSegmentReader *, PRUint32, PRUint32 *); \
nsresult WriteSegments(nsAHttpSegmentWriter *, PRUint32, PRUint32 *); \
void Close(nsresult reason); \

View File

@ -562,11 +562,11 @@ nsHttpConnection::CanReuse()
// 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;
}

View File

@ -559,10 +559,10 @@ nsHttpPipeline::Caps()
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)
@ -597,7 +597,7 @@ nsHttpPipeline::ReadSegments(nsAHttpSegmentReader *reader,
}
nsresult rv;
PRUint32 avail = 0;
PRUint64 avail = 0;
if (mSendBufIn) {
rv = mSendBufIn->Available(&avail);
if (NS_FAILED(rv)) return rv;
@ -623,7 +623,8 @@ nsHttpPipeline::ReadSegments(nsAHttpSegmentReader *reader,
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;
@ -835,7 +836,8 @@ nsHttpPipeline::FillSendBuf()
if (NS_FAILED(rv)) return rv;
}
PRUint32 n, avail;
PRUint32 n;
PRUint64 avail;
nsAHttpTransaction *trans;
nsITransport *transport = Transport();
@ -849,7 +851,7 @@ nsHttpPipeline::FillSendBuf()
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) {

View File

@ -491,10 +491,10 @@ nsHttpTransaction::Caps()
return mCaps;
}
PRUint32
PRUint64
nsHttpTransaction::Available()
{
PRUint32 size;
PRUint64 size;
if (NS_FAILED(mRequestStream->Available(&size)))
size = 0;
return size;

View File

@ -141,7 +141,7 @@ private:
nsCString mReqHeaderBuf; // flattened request headers
nsCOMPtr<nsIInputStream> mRequestStream;
PRUint32 mRequestSize;
PRUint64 mRequestSize;
nsAHttpConnection *mConnection; // hard ref
nsHttpConnectionInfo *mConnInfo; // hard ref

View File

@ -721,7 +721,7 @@ public:
#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

View File

@ -87,8 +87,10 @@ nsFTPDirListingConv::OnDataAvailable(nsIRequest* request, nsISupports *ctxt,
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);

View File

@ -78,6 +78,12 @@ TestConverter::AsyncConvertData(const char *aFromType,
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
@ -94,9 +100,19 @@ TestConverter::OnDataAvailable(nsIRequest* request,
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

View File

@ -62,9 +62,11 @@ public:
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;
@ -95,6 +97,11 @@ NS_IMPL_ISUPPORTS2(EndListener,
// 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;
@ -106,10 +113,20 @@ nsresult SendData(const char * aData, nsIStreamListener* aListener, nsIRequest*
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)

View File

@ -501,9 +501,9 @@ nsSAXXMLReader::ParseFromStream(nsIInputStream *aStream,
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;
@ -516,8 +516,13 @@ nsSAXXMLReader::ParseFromStream(nsIInputStream *aStream,
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

View File

@ -519,21 +519,24 @@ RDFXMLDataSourceImpl::BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer)
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;
}

View File

@ -2775,7 +2775,7 @@ nsCryptoHash::Update(const PRUint8 *data, PRUint32 len)
}
NS_IMETHODIMP
nsCryptoHash::UpdateFromStream(nsIInputStream *data, PRUint32 len)
nsCryptoHash::UpdateFromStream(nsIInputStream *data, PRUint32 aLen)
{
if (!mInitialized)
return NS_ERROR_NOT_INITIALIZED;
@ -2783,7 +2783,7 @@ nsCryptoHash::UpdateFromStream(nsIInputStream *data, PRUint32 len)
if (!data)
return NS_ERROR_INVALID_ARG;
PRUint32 n;
PRUint64 n;
nsresult rv = data->Available(&n);
if (NS_FAILED(rv))
return rv;
@ -2791,7 +2791,8 @@ nsCryptoHash::UpdateFromStream(nsIInputStream *data, PRUint32 len)
// 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,
@ -2809,7 +2810,7 @@ nsCryptoHash::UpdateFromStream(nsIInputStream *data, PRUint32 len)
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);
@ -2975,7 +2976,7 @@ NS_IMETHODIMP nsCryptoHMAC::UpdateFromStream(nsIInputStream *aStream, PRUint32 a
if (!aStream)
return NS_ERROR_INVALID_ARG;
PRUint32 n;
PRUint64 n;
nsresult rv = aStream->Available(&n);
if (NS_FAILED(rv))
return rv;
@ -2983,8 +2984,9 @@ NS_IMETHODIMP nsCryptoHMAC::UpdateFromStream(nsIInputStream *aStream, PRUint32 a
// 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
@ -2993,15 +2995,15 @@ NS_IMETHODIMP nsCryptoHMAC::UpdateFromStream(nsIInputStream *aStream, PRUint32 a
// 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)
@ -3010,7 +3012,7 @@ NS_IMETHODIMP nsCryptoHMAC::UpdateFromStream(nsIInputStream *aStream, PRUint32 a
if (NS_SUCCEEDED(rv))
rv = Update((const PRUint8*)buffer, read);
aLen -= read;
len -= read;
}
return rv;

View File

@ -79,11 +79,14 @@ NewBufferFromStorageStream(nsIStorageStream *storageStream,
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;

View File

@ -599,11 +599,12 @@ nsFaviconService::ReplaceFaviconDataFromDataURL(nsIURI* aFaviconURI,
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*>
@ -661,11 +662,12 @@ nsFaviconService::SetFaviconDataFromDataURL(nsIURI* aFaviconURI,
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*>

View File

@ -590,9 +590,12 @@ NS_IMETHODIMP AsyncWriteIconToDisk::Run()
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

View File

@ -159,14 +159,18 @@ EncodeInputStream(nsIInputStream *aInputStream,
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;

View File

@ -304,7 +304,7 @@ nsBinaryOutputStream::PutBuffer(char* aBuffer, PRUint32 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);

View File

@ -56,7 +56,7 @@ native nsWriteSegmentFun(nsWriteSegmentFun);
* 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
{
/**
@ -80,14 +80,13 @@ interface nsIInputStream : nsISupports
* 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.

View File

@ -11,7 +11,7 @@ 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
{
/**
@ -33,7 +33,7 @@ interface nsIScriptableInputStream : nsISupports
*
* @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.

View File

@ -212,7 +212,7 @@ nsInputStreamTee::Close()
}
NS_IMETHODIMP
nsInputStreamTee::Available(PRUint32 *avail)
nsInputStreamTee::Available(PRUint64 *avail)
{
NS_ENSURE_TRUE(mSource, NS_ERROR_NOT_INITIALIZED);
return mSource->Available(avail);

View File

@ -148,19 +148,19 @@ nsMultiplexInputStream::Close()
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;

View File

@ -704,15 +704,16 @@ nsPipeInputStream::Close()
}
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;
}

View File

@ -24,7 +24,7 @@ nsScriptableInputStream::Init(nsIInputStream *aInputStream) {
}
NS_IMETHODIMP
nsScriptableInputStream::Available(PRUint32 *_retval) {
nsScriptableInputStream::Available(PRUint64 *_retval) {
if (!mInputStream) return NS_ERROR_NOT_INITIALIZED;
return mInputStream->Available(_retval);
}
@ -32,16 +32,16 @@ nsScriptableInputStream::Available(PRUint32 *_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;

View File

@ -373,7 +373,7 @@ nsStorageInputStream::Close()
}
NS_IMETHODIMP
nsStorageInputStream::Available(PRUint32 *aAvailable)
nsStorageInputStream::Available(PRUint64 *aAvailable)
{
if (NS_FAILED(mStatus))
return mStatus;

View File

@ -611,20 +611,23 @@ NS_ConsumeStream(nsIInputStream *stream, PRUint32 maxCount, nsACString &result)
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;

View File

@ -178,7 +178,7 @@ nsStringInputStream::Close()
}
NS_IMETHODIMP
nsStringInputStream::Available(PRUint32 *aLength)
nsStringInputStream::Available(PRUint64 *aLength)
{
NS_ASSERTION(aLength, "null ptr");

View File

@ -177,7 +177,7 @@ FakeInputStream::Close()
}
NS_IMETHODIMP
FakeInputStream::Available(PRUint32* aAvailable)
FakeInputStream::Available(PRUint64* aAvailable)
{
*aAvailable = 0;