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(-)
This commit is contained in:
Patrick McManus 2015-01-08 14:48:52 -05:00
parent e49bf1a926
commit 175115e709
42 changed files with 203 additions and 151 deletions

View File

@ -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<ProgressEvent> event =
ProgressEvent::Constructor(aTarget, aType, init);
@ -2781,10 +2781,15 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
nsAutoCString defaultContentType;
nsCOMPtr<nsIInputStream> 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<int64_t>(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;

View File

@ -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<nsXMLHttpRequestUpload> 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<nsITimer> mProgressNotifier;
void HandleProgressTimerCallback();

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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<nsILoadGroup> loadGroup;
request->GetLoadGroup(getter_AddRefs(loadGroup));

View File

@ -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

View File

@ -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

View File

@ -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);
};

View File

@ -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__

View File

@ -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();

View File

@ -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<nsBaseChannel> 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)

View File

@ -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

View File

@ -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

View File

@ -59,8 +59,8 @@ private:
// nsIInputStream implementation.
nsCOMPtr<nsITransportEventSink> mEventSink;
nsCOMPtr<nsIInputStream> 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<nsISeekableStream> 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<nsITransportEventSink> mEventSink;
nsCOMPtr<nsIOutputStream> 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<nsISeekableStream> 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)

View File

@ -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<nsITransport> 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<nsTransportStatusEvent> event;

View File

@ -22,6 +22,9 @@
#include "nsIMIMEService.h"
#include <algorithm>
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;

View File

@ -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.

View File

@ -281,7 +281,7 @@ Http2PushTransactionBuffer::GetSecurityCallbacks(nsIInterfaceRequestor **outCB)
void
Http2PushTransactionBuffer::OnTransportStatus(nsITransport* transport,
nsresult status, uint64_t progress)
nsresult status, int64_t progress)
{
}

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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.

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -210,7 +210,7 @@ SpdyPush31TransactionBuffer::GetSecurityCallbacks(nsIInterfaceRequestor **outCB)
void
SpdyPush31TransactionBuffer::OnTransportStatus(nsITransport* transport,
nsresult status, uint64_t progress)
nsresult status, int64_t progress)
{
}

View File

@ -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);

View File

@ -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;

View File

@ -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; \

View File

@ -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<nsITransportEventSink> 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");
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

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

View File

@ -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<int64_t>(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",

View File

@ -214,7 +214,7 @@ private:
nsCString mReqHeaderBuf; // flattened request headers
nsCOMPtr<nsIInputStream> mRequestStream;
uint64_t mRequestSize;
int64_t mRequestSize;
nsRefPtr<nsAHttpConnection> mConnection;
nsRefPtr<nsHttpConnectionInfo> mConnInfo;

View File

@ -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);
}
}

View File

@ -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

View File

@ -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 <inttypes.h>
#include <stdlib.h>
#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;
}

View File

@ -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);