From 175115e709e9d3f20ccf08d3d9551ab1d8afc007 Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Thu, 8 Jan 2015 14:48:52 -0500 Subject: [PATCH] bug 1116867 - make nsIProgressEventSink and nsITransportEventSink safely scriptable r=mayhemer r=bz These scriptable interfaces use uint_64 arguments with sentinel values of UINT64_MAX. However, UINT64_MAX exceeds MAX_SAFE_INTEGER and cannot be gatewayed to/from javascript - so they cannot be used correctly. Change them to use signed 64 bit numbers and -1 as the sentinnel. C++ implementations ought to be enough to audit as the special value could never be used correctly in JS anyhow - also audited OnProgressChange() uses for downstream use of this data. --- dom/base/nsXMLHttpRequest.cpp | 19 +++++++---- dom/base/nsXMLHttpRequest.h | 10 +++--- dom/plugins/base/nsPluginStreamListenerPeer.cpp | 4 +-- .../webbrowserpersist/nsWebBrowserPersist.cpp | 14 ++++---- image/src/imgLoader.cpp | 4 +-- modules/libjar/nsJARChannel.cpp | 3 +- netwerk/base/public/nsIProgressEventSink.idl | 8 ++--- netwerk/base/public/nsITransport.idl | 8 ++--- netwerk/base/public/nsNetUtil.h | 24 ++++++++++++++ netwerk/base/src/Dashboard.cpp | 2 +- netwerk/base/src/nsBaseChannel.cpp | 12 +++---- netwerk/base/src/nsIncrementalDownload.cpp | 4 +-- netwerk/base/src/nsSocketTransport2.cpp | 5 +-- netwerk/base/src/nsStreamTransportService.cpp | 38 +++++++++++++--------- netwerk/base/src/nsTransportUtils.cpp | 12 +++---- netwerk/protocol/file/nsFileChannel.cpp | 8 +++-- netwerk/protocol/ftp/nsFtpConnectionThread.cpp | 4 +-- netwerk/protocol/http/Http2Push.cpp | 2 +- netwerk/protocol/http/Http2Session.cpp | 2 +- netwerk/protocol/http/HttpChannelChild.cpp | 31 +++++++++--------- netwerk/protocol/http/HttpChannelChild.h | 6 ++-- netwerk/protocol/http/HttpChannelParent.cpp | 4 +-- netwerk/protocol/http/HttpChannelParent.h | 4 +-- netwerk/protocol/http/NullHttpTransaction.cpp | 2 +- netwerk/protocol/http/PHttpChannel.ipdl | 2 +- netwerk/protocol/http/SpdyPush31.cpp | 2 +- netwerk/protocol/http/SpdySession31.cpp | 2 +- netwerk/protocol/http/TunnelUtils.cpp | 2 +- netwerk/protocol/http/nsAHttpTransaction.h | 4 +-- netwerk/protocol/http/nsHttpChannel.cpp | 30 +++++++++++------ netwerk/protocol/http/nsHttpConnection.cpp | 4 +-- netwerk/protocol/http/nsHttpConnectionMgr.cpp | 4 +-- netwerk/protocol/http/nsHttpPipeline.cpp | 4 +-- netwerk/protocol/http/nsHttpPipeline.h | 6 ++-- netwerk/protocol/http/nsHttpResponseHead.cpp | 2 +- netwerk/protocol/http/nsHttpResponseHead.h | 2 +- netwerk/protocol/http/nsHttpTransaction.cpp | 32 +++++++++--------- netwerk/protocol/http/nsHttpTransaction.h | 2 +- netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp | 2 +- netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp | 3 +- netwerk/test/TestIncrementalDownload.cpp | 7 ++-- uriloader/base/nsDocLoader.cpp | 14 ++++---- 42 files changed, 203 insertions(+), 151 deletions(-) --- dom/base/nsXMLHttpRequest.cpp | 19 ++++++---- dom/base/nsXMLHttpRequest.h | 10 ++--- .../base/nsPluginStreamListenerPeer.cpp | 4 +- .../webbrowserpersist/nsWebBrowserPersist.cpp | 14 +++---- image/src/imgLoader.cpp | 4 +- modules/libjar/nsJARChannel.cpp | 3 +- netwerk/base/public/nsIProgressEventSink.idl | 8 ++-- netwerk/base/public/nsITransport.idl | 8 ++-- netwerk/base/public/nsNetUtil.h | 24 ++++++++++++ netwerk/base/src/Dashboard.cpp | 2 +- netwerk/base/src/nsBaseChannel.cpp | 12 +++--- netwerk/base/src/nsIncrementalDownload.cpp | 4 +- netwerk/base/src/nsSocketTransport2.cpp | 5 ++- netwerk/base/src/nsStreamTransportService.cpp | 38 +++++++++++-------- netwerk/base/src/nsTransportUtils.cpp | 12 +++--- netwerk/protocol/file/nsFileChannel.cpp | 8 +++- .../protocol/ftp/nsFtpConnectionThread.cpp | 4 +- netwerk/protocol/http/Http2Push.cpp | 2 +- netwerk/protocol/http/Http2Session.cpp | 2 +- netwerk/protocol/http/HttpChannelChild.cpp | 31 +++++++-------- netwerk/protocol/http/HttpChannelChild.h | 6 +-- netwerk/protocol/http/HttpChannelParent.cpp | 4 +- netwerk/protocol/http/HttpChannelParent.h | 4 +- netwerk/protocol/http/NullHttpTransaction.cpp | 2 +- netwerk/protocol/http/PHttpChannel.ipdl | 2 +- netwerk/protocol/http/SpdyPush31.cpp | 2 +- netwerk/protocol/http/SpdySession31.cpp | 2 +- netwerk/protocol/http/TunnelUtils.cpp | 2 +- netwerk/protocol/http/nsAHttpTransaction.h | 4 +- netwerk/protocol/http/nsHttpChannel.cpp | 30 ++++++++++----- netwerk/protocol/http/nsHttpConnection.cpp | 4 +- netwerk/protocol/http/nsHttpConnectionMgr.cpp | 4 +- netwerk/protocol/http/nsHttpPipeline.cpp | 4 +- netwerk/protocol/http/nsHttpPipeline.h | 6 +-- netwerk/protocol/http/nsHttpResponseHead.cpp | 2 +- netwerk/protocol/http/nsHttpResponseHead.h | 2 +- netwerk/protocol/http/nsHttpTransaction.cpp | 32 ++++++++-------- netwerk/protocol/http/nsHttpTransaction.h | 2 +- .../protocol/wyciwyg/WyciwygChannelChild.cpp | 2 +- netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp | 3 +- netwerk/test/TestIncrementalDownload.cpp | 7 ++-- uriloader/base/nsDocLoader.cpp | 14 +++---- 42 files changed, 203 insertions(+), 151 deletions(-) diff --git a/dom/base/nsXMLHttpRequest.cpp b/dom/base/nsXMLHttpRequest.cpp index be870908fb2e..b4cf06041228 100644 --- a/dom/base/nsXMLHttpRequest.cpp +++ b/dom/base/nsXMLHttpRequest.cpp @@ -1477,7 +1477,7 @@ void nsXMLHttpRequest::DispatchProgressEvent(DOMEventTargetHelper* aTarget, const nsAString& aType, bool aLengthComputable, - uint64_t aLoaded, uint64_t aTotal) + int64_t aLoaded, int64_t aTotal) { NS_ASSERTION(aTarget, "null target"); NS_ASSERTION(!aType.IsEmpty(), "missing event type"); @@ -1497,7 +1497,7 @@ nsXMLHttpRequest::DispatchProgressEvent(DOMEventTargetHelper* aTarget, init.mCancelable = false; init.mLengthComputable = aLengthComputable; init.mLoaded = aLoaded; - init.mTotal = (aTotal == UINT64_MAX) ? 0 : aTotal; + init.mTotal = (aTotal == -1) ? 0 : aTotal; nsRefPtr event = ProgressEvent::Constructor(aTarget, aType, init); @@ -2781,10 +2781,15 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable& aBody) nsAutoCString defaultContentType; nsCOMPtr postDataStream; + uint64_t size_u64; rv = GetRequestBody(aVariant, aBody, getter_AddRefs(postDataStream), - &mUploadTotal, defaultContentType, charset); + &size_u64, defaultContentType, charset); NS_ENSURE_SUCCESS(rv, rv); + // make sure it fits within js MAX_SAFE_INTEGER + mUploadTotal = + net::InScriptableRange(size_u64) ? static_cast(size_u64) : -1; + if (postDataStream) { // If no content type header was set by the client, we set it to // application/xml. @@ -3588,18 +3593,18 @@ nsXMLHttpRequest::MaybeDispatchProgressEvents(bool aFinalProgress) } NS_IMETHODIMP -nsXMLHttpRequest::OnProgress(nsIRequest *aRequest, nsISupports *aContext, uint64_t aProgress, uint64_t aProgressMax) +nsXMLHttpRequest::OnProgress(nsIRequest *aRequest, nsISupports *aContext, int64_t aProgress, int64_t aProgressMax) { // We're uploading if our state is XML_HTTP_REQUEST_OPENED or // XML_HTTP_REQUEST_SENT bool upload = !!((XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT) & mState); // When uploading, OnProgress reports also headers in aProgress and aProgressMax. // So, try to remove the headers, if possible. - bool lengthComputable = (aProgressMax != UINT64_MAX); + bool lengthComputable = (aProgressMax != -1); if (upload) { - uint64_t loaded = aProgress; + int64_t loaded = aProgress; if (lengthComputable) { - uint64_t headerSize = aProgressMax - mUploadTotal; + int64_t headerSize = aProgressMax - mUploadTotal; loaded -= headerSize; } mUploadLengthComputable = lengthComputable; diff --git a/dom/base/nsXMLHttpRequest.h b/dom/base/nsXMLHttpRequest.h index 756faf948929..a7c63c062144 100644 --- a/dom/base/nsXMLHttpRequest.h +++ b/dom/base/nsXMLHttpRequest.h @@ -549,7 +549,7 @@ public: void DispatchProgressEvent(mozilla::DOMEventTargetHelper* aTarget, const nsAString& aType, bool aLengthComputable, - uint64_t aLoaded, uint64_t aTotal); + int64_t aLoaded, int64_t aTotal); // Dispatch the "progress" event on the XHR or XHR.upload object if we've // received data since the last "progress" event. Also dispatches @@ -724,8 +724,8 @@ protected: uint32_t mState; nsRefPtr mUpload; - uint64_t mUploadTransferred; - uint64_t mUploadTotal; + int64_t mUploadTransferred; + int64_t mUploadTotal; bool mUploadLengthComputable; bool mUploadComplete; bool mProgressSinceLastProgressEvent; @@ -744,7 +744,7 @@ protected: bool mWarnAboutMultipartHtml; bool mWarnAboutSyncHtml; bool mLoadLengthComputable; - uint64_t mLoadTotal; // 0 if not known. + int64_t mLoadTotal; // 0 if not known. // Amount of script-exposed (i.e. after undoing gzip compresion) data // received. uint64_t mDataAvailable; @@ -755,7 +755,7 @@ protected: // mDataReceived except between the OnProgress that changes mLoadTransferred // and the corresponding OnDataAvailable (which changes mDataReceived). // Ordering of OnProgress and OnDataAvailable is undefined. - uint64_t mLoadTransferred; + int64_t mLoadTransferred; nsCOMPtr mProgressNotifier; void HandleProgressTimerCallback(); diff --git a/dom/plugins/base/nsPluginStreamListenerPeer.cpp b/dom/plugins/base/nsPluginStreamListenerPeer.cpp index 5f4b2595bcc4..920b19d6c302 100644 --- a/dom/plugins/base/nsPluginStreamListenerPeer.cpp +++ b/dom/plugins/base/nsPluginStreamListenerPeer.cpp @@ -572,8 +572,8 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request, NS_IMETHODIMP nsPluginStreamListenerPeer::OnProgress(nsIRequest *request, nsISupports* aContext, - uint64_t aProgress, - uint64_t aProgressMax) + int64_t aProgress, + int64_t aProgressMax) { nsresult rv = NS_OK; return rv; diff --git a/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp b/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp index a55ece29612a..96baf4d2a10e 100644 --- a/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp +++ b/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp @@ -910,10 +910,10 @@ nsWebBrowserPersist::OnDataAvailable( //***************************************************************************** /* void onProgress (in nsIRequest request, in nsISupports ctxt, - in unsigned long long aProgress, in unsigned long long aProgressMax); */ + in long long aProgress, in long long aProgressMax); */ NS_IMETHODIMP nsWebBrowserPersist::OnProgress( - nsIRequest *request, nsISupports *ctxt, uint64_t aProgress, - uint64_t aProgressMax) + nsIRequest *request, nsISupports *ctxt, int64_t aProgress, + int64_t aProgressMax) { if (!mProgressListener) { @@ -925,16 +925,16 @@ NS_IMETHODIMP nsWebBrowserPersist::OnProgress( OutputData *data = mOutputMap.Get(keyPtr); if (data) { - data->mSelfProgress = int64_t(aProgress); - data->mSelfProgressMax = int64_t(aProgressMax); + data->mSelfProgress = aProgress; + data->mSelfProgressMax = aProgressMax; } else { UploadData *upData = mUploadList.Get(keyPtr); if (upData) { - upData->mSelfProgress = int64_t(aProgress); - upData->mSelfProgressMax = int64_t(aProgressMax); + upData->mSelfProgress = aProgress; + upData->mSelfProgressMax = aProgressMax; } } diff --git a/image/src/imgLoader.cpp b/image/src/imgLoader.cpp index 94aa7790f244..11267496c24d 100644 --- a/image/src/imgLoader.cpp +++ b/image/src/imgLoader.cpp @@ -460,8 +460,8 @@ NS_IMPL_ISUPPORTS(nsProgressNotificationProxy, NS_IMETHODIMP nsProgressNotificationProxy::OnProgress(nsIRequest* request, nsISupports* ctxt, - uint64_t progress, - uint64_t progressMax) + int64_t progress, + int64_t progressMax) { nsCOMPtr loadGroup; request->GetLoadGroup(getter_AddRefs(loadGroup)); diff --git a/modules/libjar/nsJARChannel.cpp b/modules/libjar/nsJARChannel.cpp index 67f5b2262d79..3efa1702bc55 100644 --- a/modules/libjar/nsJARChannel.cpp +++ b/modules/libjar/nsJARChannel.cpp @@ -485,8 +485,7 @@ nsJARChannel::FireOnProgress(uint64_t aProgress) MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(mProgressSink); - mProgressSink->OnProgress(this, nullptr, aProgress, - uint64_t(mContentLength)); + mProgressSink->OnProgress(this, nullptr, aProgress, mContentLength); } nsresult diff --git a/netwerk/base/public/nsIProgressEventSink.idl b/netwerk/base/public/nsIProgressEventSink.idl index 8b97fa182c99..68f8bf05971a 100644 --- a/netwerk/base/public/nsIProgressEventSink.idl +++ b/netwerk/base/public/nsIProgressEventSink.idl @@ -27,7 +27,7 @@ interface nsIRequest; * NOTE: This interface is actually not specific to channels and may be used * with other implementations of nsIRequest. */ -[scriptable, uuid(D974C99E-4148-4df9-8D98-DE834A2F6462)] +[scriptable, uuid(87d55fba-cb7e-4f38-84c1-5c6c2b2a55e9)] interface nsIProgressEventSink : nsISupports { /** @@ -44,12 +44,12 @@ interface nsIProgressEventSink : nsISupports * number of bytes transfered thus far. * @param aProgressMax * numeric value indicating maximum number of bytes that will be - * transfered (or 0xFFFFFFFFFFFFFFFF if total is unknown). + * transfered (or -1 if total is unknown). */ void onProgress(in nsIRequest aRequest, in nsISupports aContext, - in unsigned long long aProgress, - in unsigned long long aProgressMax); + in long long aProgress, + in long long aProgressMax); /** * Called to notify the event sink with a status message for the given diff --git a/netwerk/base/public/nsITransport.idl b/netwerk/base/public/nsITransport.idl index a7bf364d162f..2730c3a29a49 100644 --- a/netwerk/base/public/nsITransport.idl +++ b/netwerk/base/public/nsITransport.idl @@ -24,7 +24,7 @@ interface nsIEventTarget; * socket transport, these events can include status about the connection. * See nsISocketTransport for more info about socket transport specifics. */ -[scriptable, uuid(d8786c64-eb49-4a0b-b42c-0936a745fbe8)] +[scriptable, uuid(2a8c6334-a5e6-4ec3-9865-1256541446fb)] interface nsITransport : nsISupports { /** @@ -154,10 +154,10 @@ interface nsITransportEventSink : nsISupports * of the status code. this value is relative to aProgressMax. * @param aProgressMax * the maximum amount of data that will be read or written. if - * unknown, 0xFFFFFFFF will be passed. + * unknown, -1 will be passed. */ void onTransportStatus(in nsITransport aTransport, in nsresult aStatus, - in unsigned long long aProgress, - in unsigned long long aProgressMax); + in long long aProgress, + in long long aProgressMax); }; diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 5656cb5d2988..d4a5d5dbad77 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -2769,4 +2769,28 @@ bool NS_IsReasonableHTTPHeaderValue(const nsACString& aValue); */ bool NS_IsValidHTTPToken(const nsACString& aToken); +namespace mozilla { +namespace net { + +const static uint64_t kJS_MAX_SAFE_UINTEGER = +9007199254740991ULL; +const static int64_t kJS_MIN_SAFE_INTEGER = -9007199254740991LL; +const static int64_t kJS_MAX_SAFE_INTEGER = +9007199254740991LL; + +// Make sure a 64bit value can be captured by JS MAX_SAFE_INTEGER +inline bool +InScriptableRange(int64_t val) +{ + return (val <= kJS_MAX_SAFE_INTEGER) && (val >= kJS_MIN_SAFE_INTEGER); +} + +// Make sure a 64bit value can be captured by JS MAX_SAFE_INTEGER +inline bool +InScriptableRange(uint64_t val) +{ + return val <= kJS_MAX_SAFE_UINTEGER; +} + +} // namespace mozilla +} // namespace mozilla::net + #endif // !nsNetUtil_h__ diff --git a/netwerk/base/src/Dashboard.cpp b/netwerk/base/src/Dashboard.cpp index 8348ef3b8fff..1955d363e414 100644 --- a/netwerk/base/src/Dashboard.cpp +++ b/netwerk/base/src/Dashboard.cpp @@ -168,7 +168,7 @@ NS_IMPL_ISUPPORTS(ConnectionData, nsITransportEventSink, nsITimerCallback) NS_IMETHODIMP ConnectionData::OnTransportStatus(nsITransport *aTransport, nsresult aStatus, - uint64_t aProgress, uint64_t aProgressMax) + int64_t aProgress, int64_t aProgressMax) { if (aStatus == NS_NET_STATUS_CONNECTED_TO) { StopTimer(); diff --git a/netwerk/base/src/nsBaseChannel.cpp b/netwerk/base/src/nsBaseChannel.cpp index 7d0b81f45645..841e70f19bcb 100644 --- a/netwerk/base/src/nsBaseChannel.cpp +++ b/netwerk/base/src/nsBaseChannel.cpp @@ -653,7 +653,7 @@ nsBaseChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt) NS_IMETHODIMP nsBaseChannel::OnTransportStatus(nsITransport *transport, nsresult status, - uint64_t progress, uint64_t progressMax) + int64_t progress, int64_t progressMax) { // In some cases, we may wish to suppress transport-layer status events. @@ -796,19 +796,19 @@ nsBaseChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt, nsresult rv = mListener->OnDataAvailable(this, mListenerContext, stream, offset, count); if (mSynthProgressEvents && NS_SUCCEEDED(rv)) { - uint64_t prog = offset + count; + int64_t prog = offset + count; if (NS_IsMainThread()) { OnTransportStatus(nullptr, NS_NET_STATUS_READING, prog, mContentLength); } else { class OnTransportStatusAsyncEvent : public nsRunnable { nsRefPtr mChannel; - uint64_t mProgress; - uint64_t mContentLength; + int64_t mProgress; + int64_t mContentLength; public: OnTransportStatusAsyncEvent(nsBaseChannel* aChannel, - uint64_t aProgress, - uint64_t aContentLength) + int64_t aProgress, + int64_t aContentLength) : mChannel(aChannel), mProgress(aProgress), mContentLength(aContentLength) diff --git a/netwerk/base/src/nsIncrementalDownload.cpp b/netwerk/base/src/nsIncrementalDownload.cpp index d13a81213ab7..2f9cf5ce6105 100644 --- a/netwerk/base/src/nsIncrementalDownload.cpp +++ b/netwerk/base/src/nsIncrementalDownload.cpp @@ -205,8 +205,8 @@ nsIncrementalDownload::UpdateProgress() if (mProgressSink) mProgressSink->OnProgress(this, mObserverContext, - uint64_t(int64_t(mCurrentSize) + mChunkLen), - uint64_t(int64_t(mTotalSize))); + mCurrentSize + mChunkLen, + mTotalSize); } nsresult diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp index 8a24d4f69784..752869385879 100644 --- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -983,8 +983,9 @@ nsSocketTransport::SendStatus(nsresult status) break; } } - if (sink) - sink->OnTransportStatus(this, status, progress, UINT64_MAX); + if (sink) { + sink->OnTransportStatus(this, status, progress, -1); + } } nsresult diff --git a/netwerk/base/src/nsStreamTransportService.cpp b/netwerk/base/src/nsStreamTransportService.cpp index 78fdc1f23c4e..3e7730e679be 100644 --- a/netwerk/base/src/nsStreamTransportService.cpp +++ b/netwerk/base/src/nsStreamTransportService.cpp @@ -59,8 +59,8 @@ private: // nsIInputStream implementation. nsCOMPtr mEventSink; nsCOMPtr mSource; - uint64_t mOffset; - uint64_t mLimit; + int64_t mOffset; + int64_t mLimit; bool mCloseWhenDone; bool mFirstTime; @@ -174,7 +174,7 @@ nsInputStreamTransport::Read(char *buf, uint32_t count, uint32_t *result) mFirstTime = false; if (mOffset != 0) { // read from current position if offset equal to max - if (mOffset != UINT64_MAX) { + if (mOffset != -1) { nsCOMPtr seekable = do_QueryInterface(mSource); if (seekable) seekable->Seek(nsISeekableStream::NS_SEEK_SET, mOffset); @@ -185,10 +185,13 @@ nsInputStreamTransport::Read(char *buf, uint32_t count, uint32_t *result) } // limit amount read - uint64_t max = mLimit - mOffset; - if (max == 0) { - *result = 0; - return NS_OK; + uint64_t max = count; + if (mLimit != -1) { + max = mLimit - mOffset; + if (max == 0) { + *result = 0; + return NS_OK; + } } if (count > max) @@ -236,8 +239,8 @@ public: NS_DECL_NSIOUTPUTSTREAM nsOutputStreamTransport(nsIOutputStream *sink, - uint64_t offset, - uint64_t limit, + int64_t offset, + int64_t limit, bool closeWhenDone) : mSink(sink) , mOffset(offset) @@ -259,8 +262,8 @@ private: // nsIOutputStream implementation. nsCOMPtr mEventSink; nsCOMPtr mSink; - uint64_t mOffset; - uint64_t mLimit; + int64_t mOffset; + int64_t mLimit; bool mCloseWhenDone; bool mFirstTime; @@ -374,7 +377,7 @@ nsOutputStreamTransport::Write(const char *buf, uint32_t count, uint32_t *result mFirstTime = false; if (mOffset != 0) { // write to current position if offset equal to max - if (mOffset != UINT64_MAX) { + if (mOffset != -1) { nsCOMPtr seekable = do_QueryInterface(mSink); if (seekable) seekable->Seek(nsISeekableStream::NS_SEEK_SET, mOffset); @@ -385,10 +388,13 @@ nsOutputStreamTransport::Write(const char *buf, uint32_t count, uint32_t *result } // limit amount written - uint64_t max = mLimit - mOffset; - if (max == 0) { - *result = 0; - return NS_OK; + uint64_t max = count; + if (mLimit != -1) { + max = mLimit - mOffset; + if (max == 0) { + *result = 0; + return NS_OK; + } } if (count > max) diff --git a/netwerk/base/src/nsTransportUtils.cpp b/netwerk/base/src/nsTransportUtils.cpp index 25bae8569ae9..303ef5668926 100644 --- a/netwerk/base/src/nsTransportUtils.cpp +++ b/netwerk/base/src/nsTransportUtils.cpp @@ -56,8 +56,8 @@ public: nsTransportStatusEvent(nsTransportEventSinkProxy *proxy, nsITransport *transport, nsresult status, - uint64_t progress, - uint64_t progressMax) + int64_t progress, + int64_t progressMax) : mProxy(proxy) , mTransport(transport) , mStatus(status) @@ -87,8 +87,8 @@ public: // parameters to OnTransportStatus nsCOMPtr mTransport; nsresult mStatus; - uint64_t mProgress; - uint64_t mProgressMax; + int64_t mProgress; + int64_t mProgressMax; }; NS_IMPL_ISUPPORTS(nsTransportEventSinkProxy, nsITransportEventSink) @@ -96,8 +96,8 @@ NS_IMPL_ISUPPORTS(nsTransportEventSinkProxy, nsITransportEventSink) NS_IMETHODIMP nsTransportEventSinkProxy::OnTransportStatus(nsITransport *transport, nsresult status, - uint64_t progress, - uint64_t progressMax) + int64_t progress, + int64_t progressMax) { nsresult rv = NS_OK; nsRefPtr event; diff --git a/netwerk/protocol/file/nsFileChannel.cpp b/netwerk/protocol/file/nsFileChannel.cpp index 4a3dbb56ae33..0d0760c88484 100644 --- a/netwerk/protocol/file/nsFileChannel.cpp +++ b/netwerk/protocol/file/nsFileChannel.cpp @@ -22,6 +22,9 @@ #include "nsIMIMEService.h" #include +using namespace mozilla; +using namespace mozilla::net; + //----------------------------------------------------------------------------- class nsFileCopyEvent : public nsRunnable { @@ -453,8 +456,9 @@ nsFileChannel::SetUploadStream(nsIInputStream *stream, nsresult rv = mUploadStream->Available(&avail); if (NS_FAILED(rv)) return rv; - if (avail < INT64_MAX) - mUploadLength = avail; + // if this doesn't fit in the javascript MAX_SAFE_INTEGER + // pretend we don't know the size + mUploadLength = InScriptableRange(avail) ? avail : -1; } } else { mUploadLength = -1; diff --git a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp index 010267491117..2ecb1a8ab7a8 100644 --- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp +++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp @@ -80,7 +80,7 @@ nsFtpState::nsFtpState() , mReceivedControlData(false) , mTryingCachedControl(false) , mRETRFailed(false) - , mFileSize(UINT64_MAX) + , mFileSize(kJS_MAX_SAFE_UINTEGER) , mServerType(FTP_GENERIC_TYPE) , mAction(GET) , mAnonymous(true) @@ -2169,7 +2169,7 @@ nsFtpState::ConvertDirspecFromVMS(nsCString& dirSpec) NS_IMETHODIMP nsFtpState::OnTransportStatus(nsITransport *transport, nsresult status, - uint64_t progress, uint64_t progressMax) + int64_t progress, int64_t progressMax) { // Mix signals from both the control and data connections. diff --git a/netwerk/protocol/http/Http2Push.cpp b/netwerk/protocol/http/Http2Push.cpp index e17eeefb728c..c54ec7152991 100644 --- a/netwerk/protocol/http/Http2Push.cpp +++ b/netwerk/protocol/http/Http2Push.cpp @@ -281,7 +281,7 @@ Http2PushTransactionBuffer::GetSecurityCallbacks(nsIInterfaceRequestor **outCB) void Http2PushTransactionBuffer::OnTransportStatus(nsITransport* transport, - nsresult status, uint64_t progress) + nsresult status, int64_t progress) { } diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp index 74476e1c28dd..a4c01bb003b4 100644 --- a/netwerk/protocol/http/Http2Session.cpp +++ b/netwerk/protocol/http/Http2Session.cpp @@ -2225,7 +2225,7 @@ Http2Session::RecvAltSvc(Http2Session *self) void Http2Session::OnTransportStatus(nsITransport* aTransport, - nsresult aStatus, uint64_t aProgress) + nsresult aStatus, int64_t aProgress) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index d9e2a59c53d4..ee084de5544f 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -531,7 +531,7 @@ HttpChannelChild::DoOnStatus(nsIRequest* aRequest, nsresult status) } void -HttpChannelChild::DoOnProgress(nsIRequest* aRequest, uint64_t progress, uint64_t progressMax) +HttpChannelChild::DoOnProgress(nsIRequest* aRequest, int64_t progress, int64_t progressMax) { LOG(("HttpChannelChild::DoOnProgress [this=%p]\n", this)); if (mCanceled) @@ -549,7 +549,8 @@ HttpChannelChild::DoOnProgress(nsIRequest* aRequest, uint64_t progress, uint64_t // OnProgress // if (progress > 0) { - MOZ_ASSERT(progress <= progressMax, "unexpected progress values"); + MOZ_ASSERT((progressMax == -1) || (progress <= progressMax), + "unexpected progress values"); mProgressSink->OnProgress(aRequest, nullptr, progress, progressMax); } } @@ -692,8 +693,8 @@ class ProgressEvent : public ChannelEvent { public: ProgressEvent(HttpChannelChild* child, - const uint64_t& progress, - const uint64_t& progressMax) + const int64_t& progress, + const int64_t& progressMax) : mChild(child) , mProgress(progress) , mProgressMax(progressMax) {} @@ -701,12 +702,12 @@ class ProgressEvent : public ChannelEvent void Run() { mChild->OnProgress(mProgress, mProgressMax); } private: HttpChannelChild* mChild; - uint64_t mProgress, mProgressMax; + int64_t mProgress, mProgressMax; }; bool -HttpChannelChild::RecvOnProgress(const uint64_t& progress, - const uint64_t& progressMax) +HttpChannelChild::RecvOnProgress(const int64_t& progress, + const int64_t& progressMax) { if (mEventQ->ShouldEnqueue()) { mEventQ->Enqueue(new ProgressEvent(this, progress, progressMax)); @@ -717,10 +718,10 @@ HttpChannelChild::RecvOnProgress(const uint64_t& progress, } void -HttpChannelChild::OnProgress(const uint64_t& progress, - const uint64_t& progressMax) +HttpChannelChild::OnProgress(const int64_t& progress, + const int64_t& progressMax) { - LOG(("HttpChannelChild::OnProgress [this=%p progress=%llu/%llu]\n", + LOG(("HttpChannelChild::OnProgress [this=%p progress=%lld/%lld]\n", this, progress, progressMax)); if (mCanceled) @@ -737,7 +738,8 @@ HttpChannelChild::OnProgress(const uint64_t& progress, if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending) { if (progress > 0) { - MOZ_ASSERT(progress <= progressMax, "unexpected progress values"); + MOZ_ASSERT((progressMax == -1) || (progress <= progressMax), + "unexpected progress values"); mProgressSink->OnProgress(this, nullptr, progress, progressMax); } } @@ -1373,7 +1375,7 @@ InterceptStreamListener::OnStatus(nsIRequest* aRequest, nsISupports* aContext, NS_IMETHODIMP InterceptStreamListener::OnProgress(nsIRequest* aRequest, nsISupports* aContext, - uint64_t aProgress, uint64_t aProgressMax) + int64_t aProgress, int64_t aProgressMax) { mOwner->DoOnProgress(mOwner, aProgress, aProgressMax); return NS_OK; @@ -1396,9 +1398,8 @@ InterceptStreamListener::OnDataAvailable(nsIRequest* aRequest, nsISupports* aCon OnStatus(mOwner, aContext, NS_NET_STATUS_READING, NS_ConvertUTF8toUTF16(host).get()); - uint64_t progressMax(uint64_t(mOwner->GetResponseHead()->ContentLength())); - uint64_t progress = aOffset + uint64_t(aCount); - OnProgress(mOwner, aContext, progress, progressMax); + int64_t progress = aOffset + aCount; + OnProgress(mOwner, aContext, progress, mOwner->GetResponseHead()->ContentLength()); } mOwner->DoOnDataAvailable(mOwner, mContext, aInputStream, aOffset, aCount); diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h index 9f60ac42d67e..53857a54169a 100644 --- a/netwerk/protocol/http/HttpChannelChild.h +++ b/netwerk/protocol/http/HttpChannelChild.h @@ -126,7 +126,7 @@ protected: const uint64_t& offset, const uint32_t& count) MOZ_OVERRIDE; bool RecvOnStopRequest(const nsresult& statusCode, const ResourceTimingStruct& timing) MOZ_OVERRIDE; - bool RecvOnProgress(const uint64_t& progress, const uint64_t& progressMax) MOZ_OVERRIDE; + bool RecvOnProgress(const int64_t& progress, const int64_t& progressMax) MOZ_OVERRIDE; bool RecvOnStatus(const nsresult& status) MOZ_OVERRIDE; bool RecvFailedAsyncOpen(const nsresult& status) MOZ_OVERRIDE; bool RecvRedirect1Begin(const uint32_t& newChannel, @@ -148,7 +148,7 @@ private: void DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext); void DoOnStatus(nsIRequest* aRequest, nsresult status); - void DoOnProgress(nsIRequest* aRequest, uint64_t progress, uint64_t progressMax); + void DoOnProgress(nsIRequest* aRequest, int64_t progress, int64_t progressMax); void DoOnDataAvailable(nsIRequest* aRequest, nsISupports* aContext, nsIInputStream* aStream, uint64_t offset, uint32_t count); void DoPreOnStopRequest(nsresult aStatus); @@ -212,7 +212,7 @@ private: const uint64_t& offset, const uint32_t& count); void OnStopRequest(const nsresult& channelStatus, const ResourceTimingStruct& timing); - void OnProgress(const uint64_t& progress, const uint64_t& progressMax); + void OnProgress(const int64_t& progress, const int64_t& progressMax); void OnStatus(const nsresult& status); void FailedAsyncOpen(const nsresult& status); void HandleAsyncAbort(); diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index 818df3be42a7..c514807f8c64 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -819,8 +819,8 @@ HttpChannelParent::OnDataAvailable(nsIRequest *aRequest, NS_IMETHODIMP HttpChannelParent::OnProgress(nsIRequest *aRequest, nsISupports *aContext, - uint64_t aProgress, - uint64_t aProgressMax) + int64_t aProgress, + int64_t aProgressMax) { // OnStatus has always just set mStoredStatus. If it indicates this precedes // OnDataAvailable, store and ODA will send to child. diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h index c3a446502f55..1352a5107e9b 100644 --- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -163,8 +163,8 @@ private: // state for combining OnStatus/OnProgress with OnDataAvailable // into one IPDL call to child. nsresult mStoredStatus; - uint64_t mStoredProgress; - uint64_t mStoredProgressMax; + int64_t mStoredProgress; + int64_t mStoredProgressMax; bool mSentRedirect1Begin : 1; bool mSentRedirect1BeginFailed : 1; diff --git a/netwerk/protocol/http/NullHttpTransaction.cpp b/netwerk/protocol/http/NullHttpTransaction.cpp index e8542ebfbb1c..8a352716f750 100644 --- a/netwerk/protocol/http/NullHttpTransaction.cpp +++ b/netwerk/protocol/http/NullHttpTransaction.cpp @@ -147,7 +147,7 @@ NullHttpTransaction::GetSecurityCallbacks(nsIInterfaceRequestor **outCB) void NullHttpTransaction::OnTransportStatus(nsITransport* transport, - nsresult status, uint64_t progress) + nsresult status, int64_t progress) { if (mActivityDistributor) { NS_DispatchToMainThread(new CallObserveActivity(mActivityDistributor, diff --git a/netwerk/protocol/http/PHttpChannel.ipdl b/netwerk/protocol/http/PHttpChannel.ipdl index 7f2c6e5eb5c8..a0edc6a32d5c 100644 --- a/netwerk/protocol/http/PHttpChannel.ipdl +++ b/netwerk/protocol/http/PHttpChannel.ipdl @@ -107,7 +107,7 @@ child: OnStopRequest(nsresult channelStatus, ResourceTimingStruct timing); - OnProgress(uint64_t progress, uint64_t progressMax); + OnProgress(int64_t progress, int64_t progressMax); OnStatus(nsresult status); diff --git a/netwerk/protocol/http/SpdyPush31.cpp b/netwerk/protocol/http/SpdyPush31.cpp index 8fb7d795b594..26b592415ef3 100644 --- a/netwerk/protocol/http/SpdyPush31.cpp +++ b/netwerk/protocol/http/SpdyPush31.cpp @@ -210,7 +210,7 @@ SpdyPush31TransactionBuffer::GetSecurityCallbacks(nsIInterfaceRequestor **outCB) void SpdyPush31TransactionBuffer::OnTransportStatus(nsITransport* transport, - nsresult status, uint64_t progress) + nsresult status, int64_t progress) { } diff --git a/netwerk/protocol/http/SpdySession31.cpp b/netwerk/protocol/http/SpdySession31.cpp index a6bc9cff54ff..60aaf60036b0 100644 --- a/netwerk/protocol/http/SpdySession31.cpp +++ b/netwerk/protocol/http/SpdySession31.cpp @@ -1767,7 +1767,7 @@ SpdySession31::HandleCredential(SpdySession31 *self) void SpdySession31::OnTransportStatus(nsITransport* aTransport, nsresult aStatus, - uint64_t aProgress) + int64_t aProgress) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp index fc1a93144287..4218dad4a620 100644 --- a/netwerk/protocol/http/TunnelUtils.cpp +++ b/netwerk/protocol/http/TunnelUtils.cpp @@ -556,7 +556,7 @@ TLSFilterTransaction::GetSecurityCallbacks(nsIInterfaceRequestor **outCB) void TLSFilterTransaction::OnTransportStatus(nsITransport* aTransport, - nsresult aStatus, uint64_t aProgress) + nsresult aStatus, int64_t aProgress) { if (!mTransaction) { return; diff --git a/netwerk/protocol/http/nsAHttpTransaction.h b/netwerk/protocol/http/nsAHttpTransaction.h index 4b14ec4d35db..3fd49cfb6476 100644 --- a/netwerk/protocol/http/nsAHttpTransaction.h +++ b/netwerk/protocol/http/nsAHttpTransaction.h @@ -55,7 +55,7 @@ public: // called to report socket status (see nsITransportEventSink) virtual void OnTransportStatus(nsITransport* transport, - nsresult status, uint64_t progress) = 0; + nsresult status, int64_t progress) = 0; // called to check the transaction status. virtual bool IsDone() = 0; @@ -198,7 +198,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpTransaction, NS_AHTTPTRANSACTION_IID) nsAHttpConnection *Connection() MOZ_OVERRIDE; \ void GetSecurityCallbacks(nsIInterfaceRequestor **) MOZ_OVERRIDE; \ void OnTransportStatus(nsITransport* transport, \ - nsresult status, uint64_t progress) MOZ_OVERRIDE; \ + nsresult status, int64_t progress) MOZ_OVERRIDE; \ bool IsDone() MOZ_OVERRIDE; \ nsresult Status() MOZ_OVERRIDE; \ uint32_t Caps() MOZ_OVERRIDE; \ diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 29fe2324fb9c..7b8e4ee86dc5 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -5594,8 +5594,8 @@ class OnTransportStatusAsyncEvent : public nsRunnable public: OnTransportStatusAsyncEvent(nsITransportEventSink* aEventSink, nsresult aTransportStatus, - uint64_t aProgress, - uint64_t aProgressMax) + int64_t aProgress, + int64_t aProgressMax) : mEventSink(aEventSink) , mTransportStatus(aTransportStatus) , mProgress(aProgress) @@ -5616,8 +5616,8 @@ public: private: nsCOMPtr mEventSink; nsresult mTransportStatus; - uint64_t mProgress; - uint64_t mProgressMax; + int64_t mProgress; + int64_t mProgressMax; }; NS_IMETHODIMP @@ -5662,12 +5662,22 @@ nsHttpChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt, // of a byte range request, the content length stored in the cached // response headers is what we want to use here. - uint64_t progressMax(uint64_t(mResponseHead->ContentLength())); - uint64_t progress = mLogicalOffset + uint64_t(count); + int64_t progressMax(mResponseHead->ContentLength()); + int64_t progress = mLogicalOffset + count; - if (progress > progressMax) + if ((progress > progressMax) && (progressMax != -1)) { NS_WARNING("unexpected progress values - " "is server exceeding content length?"); + } + + // make sure params are in range for js + if (!InScriptableRange(progressMax)) { + progressMax = -1; + } + + if (!InScriptableRange(progress)) { + progress = -1; + } if (NS_IsMainThread()) { OnTransportStatus(nullptr, transportStatus, progress, progressMax); @@ -5796,7 +5806,7 @@ nsHttpChannel::CheckListenerChain() NS_IMETHODIMP nsHttpChannel::OnTransportStatus(nsITransport *trans, nsresult status, - uint64_t progress, uint64_t progressMax) + int64_t progress, int64_t progressMax) { MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread only"); // cache the progress sink so we don't have to query for it each time. @@ -5816,7 +5826,7 @@ nsHttpChannel::OnTransportStatus(nsITransport *trans, nsresult status, // block socket status event after Cancel or OnStopRequest has been called. if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending) { LOG(("sending progress%s notification [this=%p status=%x" - " progress=%llu/%llu]\n", + " progress=%lld/%lld]\n", (mLoadFlags & LOAD_BACKGROUND)? "" : " and status", this, status, progress, progressMax)); @@ -5828,7 +5838,7 @@ nsHttpChannel::OnTransportStatus(nsITransport *trans, nsresult status, } if (progress > 0) { - if (progress > progressMax) { + if ((progress > progressMax) && (progressMax != -1)) { NS_WARNING("unexpected progress values"); } diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp index cd60bc5d7f7e..1a2ea45a808d 100644 --- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -2080,8 +2080,8 @@ nsHttpConnection::OnOutputStreamReady(nsIAsyncOutputStream *out) NS_IMETHODIMP nsHttpConnection::OnTransportStatus(nsITransport *trans, nsresult status, - uint64_t progress, - uint64_t progressMax) + int64_t progress, + int64_t progressMax) { if (mTransaction) mTransaction->OnTransportStatus(trans, status, progress); diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 750dfafea8ba..58b101839552 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -3426,8 +3426,8 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out) NS_IMETHODIMP nsHttpConnectionMgr::nsHalfOpenSocket::OnTransportStatus(nsITransport *trans, nsresult status, - uint64_t progress, - uint64_t progressMax) + int64_t progress, + int64_t progressMax) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); diff --git a/netwerk/protocol/http/nsHttpPipeline.cpp b/netwerk/protocol/http/nsHttpPipeline.cpp index 68c8ea2f0f76..b76d87511b47 100644 --- a/netwerk/protocol/http/nsHttpPipeline.cpp +++ b/netwerk/protocol/http/nsHttpPipeline.cpp @@ -440,9 +440,9 @@ nsHttpPipeline::GetSecurityCallbacks(nsIInterfaceRequestor **result) void nsHttpPipeline::OnTransportStatus(nsITransport* transport, - nsresult status, uint64_t progress) + nsresult status, int64_t progress) { - LOG(("nsHttpPipeline::OnStatus [this=%p status=%x progress=%llu]\n", + LOG(("nsHttpPipeline::OnStatus [this=%p status=%x progress=%lld]\n", this, status, progress)); MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); diff --git a/netwerk/protocol/http/nsHttpPipeline.h b/netwerk/protocol/http/nsHttpPipeline.h index 5a0da513e926..51d62757f9c0 100644 --- a/netwerk/protocol/http/nsHttpPipeline.h +++ b/netwerk/protocol/http/nsHttpPipeline.h @@ -94,9 +94,9 @@ private: uint32_t mHttp1xTransactionCount; // For support of OnTransportStatus() - uint64_t mReceivingFromProgress; - uint64_t mSendingToProgress; - bool mSuppressSendEvents; + int64_t mReceivingFromProgress; + int64_t mSendingToProgress; + bool mSuppressSendEvents; }; }} // namespace mozilla::net diff --git a/netwerk/protocol/http/nsHttpResponseHead.cpp b/netwerk/protocol/http/nsHttpResponseHead.cpp index fb828bfe512c..511d942feedc 100644 --- a/netwerk/protocol/http/nsHttpResponseHead.cpp +++ b/netwerk/protocol/http/nsHttpResponseHead.cpp @@ -623,7 +623,7 @@ nsHttpResponseHead::Reset() mVersion = NS_HTTP_VERSION_1_1; mStatus = 200; - mContentLength = UINT64_MAX; + mContentLength = -1; mCacheControlPrivate = false; mCacheControlNoStore = false; mCacheControlNoCache = false; diff --git a/netwerk/protocol/http/nsHttpResponseHead.h b/netwerk/protocol/http/nsHttpResponseHead.h index 279535fb531f..6a14201182f1 100644 --- a/netwerk/protocol/http/nsHttpResponseHead.h +++ b/netwerk/protocol/http/nsHttpResponseHead.h @@ -22,7 +22,7 @@ class nsHttpResponseHead public: nsHttpResponseHead() : mVersion(NS_HTTP_VERSION_1_1) , mStatus(200) - , mContentLength(UINT64_MAX) + , mContentLength(-1) , mCacheControlPrivate(false) , mCacheControlNoStore(false) , mCacheControlNoCache(false) diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp index 39506818f9e1..163201a0e412 100644 --- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -367,8 +367,14 @@ nsHttpTransaction::Init(uint32_t caps, else mRequestStream = headers; - rv = mRequestStream->Available(&mRequestSize); - if (NS_FAILED(rv)) return rv; + uint64_t size_u64; + rv = mRequestStream->Available(&size_u64); + if (NS_FAILED(rv)) { + return rv; + } + + // make sure it fits within js MAX_SAFE_INTEGER + mRequestSize = InScriptableRange(size_u64) ? static_cast(size_u64) : -1; // create pipe for response stream rv = NS_NewPipe2(getter_AddRefs(mPipeIn), @@ -499,9 +505,9 @@ nsHttpTransaction::SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks) void nsHttpTransaction::OnTransportStatus(nsITransport* transport, - nsresult status, uint64_t progress) + nsresult status, int64_t progress) { - LOG(("nsHttpTransaction::OnSocketStatus [this=%p status=%x progress=%llu]\n", + LOG(("nsHttpTransaction::OnSocketStatus [this=%p status=%x progress=%lld]\n", this, status, progress)); if (TimingEnabled()) { @@ -548,7 +554,7 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport, if (status == NS_NET_STATUS_RECEIVING_FROM) return; - uint64_t progressMax; + int64_t progressMax; if (status == NS_NET_STATUS_SENDING_TO) { // suppress progress when only writing request headers @@ -562,16 +568,16 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport, if (!seekable) { LOG(("nsHttpTransaction::OnTransportStatus %p " "SENDING_TO without seekable request stream\n", this)); - return; + progress = 0; + } else { + int64_t prog = 0; + seekable->Tell(&prog); + progress = prog; } - int64_t prog = 0; - seekable->Tell(&prog); - progress = prog; - // when uploading, we include the request headers in the progress // notifications. - progressMax = mRequestSize; // XXX mRequestSize is 32-bit! + progressMax = mRequestSize; } else { progress = 0; @@ -1619,10 +1625,6 @@ nsHttpTransaction::HandleContent(char *buf, if (*contentRead) { // update count of content bytes read and report progress... mContentRead += *contentRead; - /* when uncommenting, take care of 64-bit integers w/ std::max... - if (mProgressSink) - mProgressSink->OnProgress(nullptr, nullptr, mContentRead, std::max(0, mContentLength)); - */ } LOG(("nsHttpTransaction::HandleContent [this=%p count=%u read=%u mContentRead=%lld mContentLength=%lld]\n", diff --git a/netwerk/protocol/http/nsHttpTransaction.h b/netwerk/protocol/http/nsHttpTransaction.h index 958475f9a046..f79706713096 100644 --- a/netwerk/protocol/http/nsHttpTransaction.h +++ b/netwerk/protocol/http/nsHttpTransaction.h @@ -214,7 +214,7 @@ private: nsCString mReqHeaderBuf; // flattened request headers nsCOMPtr mRequestStream; - uint64_t mRequestSize; + int64_t mRequestSize; nsRefPtr mConnection; nsRefPtr mConnInfo; diff --git a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp index a89bf48e5c6a..292d486eaea3 100644 --- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp +++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp @@ -254,7 +254,7 @@ WyciwygChannelChild::OnDataAvailable(const nsCString& data, if (mProgressSink && NS_SUCCEEDED(rv)) { mProgressSink->OnProgress(this, nullptr, offset + data.Length(), - uint64_t(mContentLength)); + mContentLength); } } diff --git a/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp b/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp index aaaec3bfcd78..7df58b202aa5 100644 --- a/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp +++ b/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp @@ -709,8 +709,7 @@ nsWyciwygChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctx, // XXX handle 64-bit stuff for real if (mProgressSink && NS_SUCCEEDED(rv)) { - mProgressSink->OnProgress(this, nullptr, offset + count, - uint64_t(mContentLength)); + mProgressSink->OnProgress(this, nullptr, offset + count, mContentLength); } return rv; // let the pump cancel on failure diff --git a/netwerk/test/TestIncrementalDownload.cpp b/netwerk/test/TestIncrementalDownload.cpp index 94079f7b9301..bb02395a9fe8 100644 --- a/netwerk/test/TestIncrementalDownload.cpp +++ b/netwerk/test/TestIncrementalDownload.cpp @@ -4,6 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include #include #include "TestCommon.h" #include "nsNetUtil.h" @@ -40,10 +41,10 @@ FetchObserver::OnStartRequest(nsIRequest *request, nsISupports *context) NS_IMETHODIMP FetchObserver::OnProgress(nsIRequest *request, nsISupports *context, - uint64_t progress, uint64_t progressMax) + int64_t progress, int64_t progressMax) { - printf("FetchObserver::OnProgress [%lu/%lu]\n", - (unsigned long)progress, (unsigned long)progressMax); + printf("FetchObserver::OnProgress [%" PRId64 "/%" PRId64 "]\n", + progress, progressMax); return NS_OK; } diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index 06b2b6689f3a..59cd99cab314 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -985,7 +985,7 @@ int64_t nsDocLoader::GetMaxTotalProgress() //////////////////////////////////////////////////////////////////////////////////// NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt, - uint64_t aProgress, uint64_t aProgressMax) + int64_t aProgress, int64_t aProgressMax) { int64_t progressDelta = 0; @@ -996,8 +996,8 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt, // Update info->mCurrentProgress before we call FireOnStateChange, // since that can make the "info" pointer invalid. int64_t oldCurrentProgress = info->mCurrentProgress; - progressDelta = int64_t(aProgress) - oldCurrentProgress; - info->mCurrentProgress = int64_t(aProgress); + progressDelta = aProgress - oldCurrentProgress; + info->mCurrentProgress = aProgress; // suppress sending STATE_TRANSFERRING if this is upload progress (see bug 240053) if (!info->mUploading && (int64_t(0) == oldCurrentProgress) && (int64_t(0) == info->mMaxProgress)) { @@ -1017,13 +1017,13 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt, // // This is the first progress notification for the entry. If - // (aMaxProgress > 0) then the content-length of the data is known, + // (aMaxProgress != -1) then the content-length of the data is known, // so update mMaxSelfProgress... Otherwise, set it to -1 to indicate // that the content-length is no longer known. // - if (uint64_t(aProgressMax) != UINT64_MAX) { - mMaxSelfProgress += int64_t(aProgressMax); - info->mMaxProgress = int64_t(aProgressMax); + if (aProgressMax != -1) { + mMaxSelfProgress += aProgressMax; + info->mMaxProgress = aProgressMax; } else { mMaxSelfProgress = int64_t(-1); info->mMaxProgress = int64_t(-1);