author | Ryan VanderMeulen <ryanvm@gmail.com> |
Wed, 08 Apr 2015 11:49:49 -0400 | |
changeset 238124 | 7fbf03927859971b3cf07c7663cd4c000eaadb73 |
parent 238123 | 55524bdeb708cca0f7b128fbe3e1e58cbece899d |
child 238183 | 8911c111a6adbd5dd6f784a63763864bafa18798 |
push id | 58132 |
push user | ryanvm@gmail.com |
push date | Wed, 08 Apr 2015 15:49:56 +0000 |
treeherder | mozilla-inbound@7fbf03927859 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1149987 |
milestone | 40.0a1 |
backs out | b62e371d61898c241efec2cb9fe7f11d0b86395d daa762fca8e68d966180ef062412224bf782c69f bdb64d5befa55cb4f57673dadaf8e58435604032 693901a4bcde177154392671ccbae2070697ea36 e7c41c8653c43605976eb5b1579303590ec35414 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -8,17 +8,16 @@ #include <algorithm> #include <stdarg.h> #include "mozilla/DebugOnly.h" #include "mozilla/FloatingPoint.h" #include "mozilla/Assertions.h" #include "mozilla/Preferences.h" -#include "mozilla/unused.h" #include "AccessCheck.h" #include "jsfriendapi.h" #include "nsContentUtils.h" #include "nsGlobalWindow.h" #include "nsIDocShell.h" #include "nsIDOMGlobalPropertyInitializer.h" #include "nsIPermissionManager.h" @@ -42,17 +41,16 @@ #include "mozilla/dom/HTMLSharedObjectElement.h" #include "mozilla/dom/HTMLEmbedElementBinding.h" #include "mozilla/dom/HTMLAppletElementBinding.h" #include "mozilla/dom/Promise.h" #include "mozilla/dom/ResolveSystemBinding.h" #include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "WorkerPrivate.h" #include "nsDOMClassInfo.h" -#include "ipc/ErrorIPCUtils.h" namespace mozilla { namespace dom { JSErrorFormatString ErrorFormatString[] = { #define MSG_DEF(_name, _argc, _exn, _str) \ { _str, _argc, _exn }, #include "mozilla/dom/Errors.msg" @@ -147,41 +145,16 @@ ErrorResult::ThrowErrorWithMessage(va_li argCount = std::min<uint16_t>(argCount, 10); while (argCount--) { message->mArgs.AppendElement(*va_arg(ap, nsString*)); } mMessage = message; } void -ErrorResult::SerializeMessage(IPC::Message* aMsg) const -{ - using namespace IPC; - MOZ_ASSERT(mMessage); - WriteParam(aMsg, mMessage->mArgs); - WriteParam(aMsg, mMessage->mErrorNumber); -} - -bool -ErrorResult::DeserializeMessage(const IPC::Message* aMsg, void** aIter) -{ - using namespace IPC; - nsAutoPtr<Message> readMessage(new Message()); - if (!ReadParam(aMsg, aIter, &readMessage->mArgs) || - !ReadParam(aMsg, aIter, &readMessage->mErrorNumber)) { - return false; - } - if (mMessage) { - delete mMessage; - } - mMessage = readMessage.forget(); - return true; -} - -void ErrorResult::ThrowTypeError(const dom::ErrNum errorNumber, ...) { va_list ap; va_start(ap, errorNumber); ThrowErrorWithMessage(ap, errorNumber, NS_ERROR_TYPE_ERR); va_end(ap); } @@ -323,47 +296,16 @@ ErrorResult::ReportNotEnoughArgsError(JS const char* memberName) { MOZ_ASSERT(ErrorCode() == NS_ERROR_XPC_NOT_ENOUGH_ARGS); nsPrintfCString errorMessage("%s.%s", ifaceName, memberName); ThrowErrorMessage(cx, dom::MSG_MISSING_ARGUMENTS, errorMessage.get()); } -ErrorResult& -ErrorResult::operator=(ErrorResult&& aRHS) -{ -#ifdef DEBUG - mMightHaveUnreportedJSException = aRHS.mMightHaveUnreportedJSException; - aRHS.mMightHaveUnreportedJSException = false; -#endif - if (aRHS.IsErrorWithMessage()) { - mMessage = aRHS.mMessage; - aRHS.mMessage = nullptr; - } else if (aRHS.IsJSException()) { - JSContext* cx = nsContentUtils::GetDefaultJSContextForThread(); - MOZ_ASSERT(cx); - mJSException.setUndefined(); - if (!js::AddRawValueRoot(cx, &mJSException, "ErrorResult::mJSException")) { - MOZ_CRASH("Could not root mJSException, we're about to OOM"); - } - mJSException = aRHS.mJSException; - aRHS.mJSException.setUndefined(); - js::RemoveRawValueRoot(cx, &aRHS.mJSException); - } else { - // Null out the union on both sides for hygiene purposes. - mMessage = aRHS.mMessage = nullptr; - } - // Note: It's important to do this last, since this affects the condition - // checks above! - mResult = aRHS.mResult; - aRHS.mResult = NS_OK; - return *this; -} - namespace dom { bool DefineConstants(JSContext* cx, JS::Handle<JSObject*> obj, const ConstantSpec* cs) { JS::Rooted<JS::Value> value(cx); for (; cs->name; ++cs) {
deleted file mode 100644 --- a/dom/bindings/ErrorIPCUtils.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* vim: set ts=2 sw=2 et tw=79: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 "ipc/IPCMessageUtils.h" -#include "mozilla/ErrorResult.h" -#include "mozilla/Assertions.h" -#include "mozilla/Move.h" - -#ifndef IPC_ErrorIPCUtils_h -#define IPC_ErrorIPCUtils_h - -namespace IPC { - -template<> -struct ParamTraits<mozilla::dom::ErrNum> : - public ContiguousEnumSerializer<mozilla::dom::ErrNum, - mozilla::dom::ErrNum(0), - mozilla::dom::ErrNum(mozilla::dom::Err_Limit)> {}; - -template<> -struct ParamTraits<mozilla::ErrorResult> -{ - typedef mozilla::ErrorResult paramType; - - static void Write(Message* aMsg, const paramType& aParam) - { - // It should be the case that mMightHaveUnreportedJSException can only be - // true when we're expecting a JS exception. We cannot send such messages - // over the IPC channel since there is no sane way of transferring the JS - // value over to the other side. Callers should never do that. - MOZ_ASSERT_IF(aParam.IsJSException(), aParam.mMightHaveUnreportedJSException); - if (aParam.IsJSException() -#ifdef DEBUG - || aParam.mMightHaveUnreportedJSException -#endif - ) { - MOZ_CRASH("Cannot encode an ErrorResult representing a Javascript exception"); - } - - WriteParam(aMsg, aParam.mResult); - WriteParam(aMsg, aParam.IsErrorWithMessage()); - if (aParam.IsErrorWithMessage()) { - aParam.SerializeMessage(aMsg); - } - } - - static bool Read(const Message* aMsg, void** aIter, paramType* aResult) - { - paramType readValue; - if (!ReadParam(aMsg, aIter, &readValue.mResult)) { - return false; - } - bool hasMessage = false; - if (!ReadParam(aMsg, aIter, &hasMessage)) { - return false; - } - if (hasMessage && !readValue.DeserializeMessage(aMsg, aIter)) { - return false; - } - *aResult = Move(readValue); - return true; - } -}; - -} - -#endif
--- a/dom/bindings/ErrorResult.h +++ b/dom/bindings/ErrorResult.h @@ -12,22 +12,16 @@ #define mozilla_ErrorResult_h #include <stdarg.h> #include "js/Value.h" #include "nscore.h" #include "nsStringGlue.h" #include "mozilla/Assertions.h" -#include "mozilla/Move.h" - -namespace IPC { -class Message; -template <typename> struct ParamTraits; -} namespace mozilla { namespace dom { enum ErrNum { #define MSG_DEF(_name, _argc, _exn, _str) \ _name, @@ -57,22 +51,16 @@ public: #ifdef DEBUG ~ErrorResult() { MOZ_ASSERT_IF(IsErrorWithMessage(), !mMessage); MOZ_ASSERT(!mMightHaveUnreportedJSException); } #endif - ErrorResult(ErrorResult&& aRHS) - { - *this = Move(aRHS); - } - ErrorResult& operator=(ErrorResult&& aRHS); - void Throw(nsresult rv) { MOZ_ASSERT(NS_FAILED(rv), "Please don't try throwing success"); MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()"); MOZ_ASSERT(rv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()"); MOZ_ASSERT(!IsErrorWithMessage(), "Don't overwrite errors with message"); MOZ_ASSERT(rv != NS_ERROR_DOM_JS_EXCEPTION, "Use ThrowJSException()"); MOZ_ASSERT(!IsJSException(), "Don't overwrite JS exceptions"); MOZ_ASSERT(rv != NS_ERROR_XPC_NOT_ENOUGH_ARGS, "Use ThrowNotEnoughArgsError()"); @@ -168,30 +156,25 @@ private: // ReportErrorWithMessage. // mJSException is set (and rooted) by ThrowJSException and unrooted // by ReportJSException. union { Message* mMessage; // valid when IsErrorWithMessage() JS::Value mJSException; // valid when IsJSException() }; - friend struct IPC::ParamTraits<ErrorResult>; - void SerializeMessage(IPC::Message* aMsg) const; - bool DeserializeMessage(const IPC::Message* aMsg, void** aIter); - #ifdef DEBUG // Used to keep track of codepaths that might throw JS exceptions, // for assertion purposes. bool mMightHaveUnreportedJSException; #endif // Not to be implemented, to make sure people always pass this by // reference, not by value. ErrorResult(const ErrorResult&) = delete; - void operator=(const ErrorResult&) = delete; void ThrowErrorWithMessage(va_list ap, const dom::ErrNum errorNumber, nsresult errorType); }; /****************************************************************************** ** Macros for checking results ******************************************************************************/
--- a/dom/bindings/Errors.msg +++ b/dom/bindings/Errors.msg @@ -68,10 +68,9 @@ MSG_DEF(MSG_FETCH_FAILED, 0, JSEXN_TYPEE MSG_DEF(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD, 0, JSEXN_TYPEERR, "HEAD or GET Request cannot have a body.") MSG_DEF(MSG_DEFINE_NON_CONFIGURABLE_PROP_ON_WINDOW, 0, JSEXN_TYPEERR, "Not allowed to define a non-configurable property on the WindowProxy object") MSG_DEF(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR, 0, JSEXN_RANGEERR, "Invalid zoom and pan value.") MSG_DEF(MSG_INVALID_TRANSFORM_ANGLE_ERROR, 0, JSEXN_RANGEERR, "Invalid transform angle.") MSG_DEF(MSG_INVALID_RESPONSE_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid response status code.") MSG_DEF(MSG_INVALID_REDIRECT_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid redirect status code.") MSG_DEF(MSG_INVALID_URL_SCHEME, 2, JSEXN_TYPEERR, "{0} URL {1} must be either http:// or https://.") MSG_DEF(MSG_RESPONSE_URL_IS_NULL, 0, JSEXN_TYPEERR, "Cannot set Response.finalURL when Response.url is null.") -MSG_DEF(MSG_RESPONSE_HAS_VARY_STAR, 0, JSEXN_TYPEERR, "Invalid Response object with a 'Vary: *' header.") MSG_DEF(MSG_BAD_FORMDATA, 0, JSEXN_TYPEERR, "Could not parse content as FormData.")
--- a/dom/bindings/moz.build +++ b/dom/bindings/moz.build @@ -1,20 +1,16 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # 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/. TEST_DIRS += ['test'] -EXPORTS.ipc += [ - 'ErrorIPCUtils.h', -] - EXPORTS.mozilla += [ 'ErrorResult.h', ] EXPORTS.mozilla.dom += [ 'AtomList.h', 'BindingDeclarations.h', 'BindingUtils.h',
--- a/dom/cache/Cache.cpp +++ b/dom/cache/Cache.cpp @@ -447,26 +447,22 @@ Cache::RecvMatchAllResponse(RequestId aR promise->MaybeReject(aRv); return; } promise->MaybeResolve(responses); } void -Cache::RecvAddAllResponse(RequestId aRequestId, - const mozilla::ErrorResult& aError) +Cache::RecvAddAllResponse(RequestId aRequestId, nsresult aRv) { nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId); - if (aError.Failed()) { - // TODO: Remove this const_cast (bug 1152078). - // It is safe for now since this ErrorResult is handed off to us by IPDL - // and is thrown into the trash afterwards. - promise->MaybeReject(const_cast<ErrorResult&>(aError)); + if (NS_FAILED(aRv)) { + promise->MaybeReject(aRv); return; } promise->MaybeResolve(JS::UndefinedHandleValue); } void Cache::RecvPutResponse(RequestId aRequestId, nsresult aRv)
--- a/dom/cache/Cache.h +++ b/dom/cache/Cache.h @@ -76,18 +76,17 @@ public: // Called when CacheChild actor is being destroyed void DestroyInternal(CacheChild* aActor); // methods forwarded from CacheChild void RecvMatchResponse(RequestId aRequestId, nsresult aRv, const PCacheResponseOrVoid& aResponse); void RecvMatchAllResponse(RequestId aRequestId, nsresult aRv, const nsTArray<PCacheResponse>& aResponses); - void RecvAddAllResponse(RequestId aRequestId, - const mozilla::ErrorResult& aError); + void RecvAddAllResponse(RequestId aRequestId, nsresult aRv); void RecvPutResponse(RequestId aRequestId, nsresult aRv); void RecvDeleteResponse(RequestId aRequestId, nsresult aRv, bool aSuccess); void RecvKeysResponse(RequestId aRequestId, nsresult aRv, const nsTArray<PCacheRequest>& aRequests); // TypeUtils methods
--- a/dom/cache/CacheChild.cpp +++ b/dom/cache/CacheChild.cpp @@ -141,23 +141,22 @@ CacheChild::RecvMatchAllResponse(const R return true; } listener->RecvMatchAllResponse(requestId, aRv, aResponses); return true; } bool -CacheChild::RecvAddAllResponse(const RequestId& requestId, - const mozilla::ErrorResult& aError) +CacheChild::RecvAddAllResponse(const RequestId& requestId, const nsresult& aRv) { NS_ASSERT_OWNINGTHREAD(CacheChild); nsRefPtr<Cache> listener = mListener; if (listener) { - listener->RecvAddAllResponse(requestId, aError); + listener->RecvAddAllResponse(requestId, aRv); } return true; } bool CacheChild::RecvPutResponse(const RequestId& aRequestId, const nsresult& aRv) { NS_ASSERT_OWNINGTHREAD(CacheChild);
--- a/dom/cache/CacheChild.h +++ b/dom/cache/CacheChild.h @@ -50,17 +50,17 @@ private: virtual bool RecvMatchResponse(const RequestId& requestId, const nsresult& aRv, const PCacheResponseOrVoid& aResponse) override; virtual bool RecvMatchAllResponse(const RequestId& requestId, const nsresult& aRv, nsTArray<PCacheResponse>&& responses) override; virtual bool RecvAddAllResponse(const RequestId& requestId, - const mozilla::ErrorResult& aError) override; + const nsresult& aRv) override; virtual bool RecvPutResponse(const RequestId& aRequestId, const nsresult& aRv) override; virtual bool RecvDeleteResponse(const RequestId& requestId, const nsresult& aRv, const bool& result) override; virtual bool RecvKeysResponse(const RequestId& requestId, const nsresult& aRv,
--- a/dom/cache/CacheParent.cpp +++ b/dom/cache/CacheParent.cpp @@ -18,17 +18,16 @@ #include "mozilla/ipc/FileDescriptorSetParent.h" #include "mozilla/ipc/PFileDescriptorSetParent.h" #include "nsCOMPtr.h" namespace mozilla { namespace dom { namespace cache { -using mozilla::dom::ErrNum; using mozilla::ipc::FileDescriptorSetParent; using mozilla::ipc::PFileDescriptorSetParent; // Declared in ActorUtils.h void DeallocPCacheParent(PCacheParent* aActor) { delete aActor; @@ -117,20 +116,17 @@ CacheParent::RecvAddAll(const RequestId& requestStreams.AppendElement(DeserializeCacheStream(aRequests[i].body())); } nsRefPtr<FetchPut> fetchPut; nsresult rv = FetchPut::Create(this, mManager, aRequestId, mCacheId, aRequests, requestStreams, getter_AddRefs(fetchPut)); if (NS_WARN_IF(NS_FAILED(rv))) { - MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR); - ErrorResult error; - error.Throw(rv); - if (!SendAddAllResponse(aRequestId, error)) { + if (!SendAddAllResponse(aRequestId, rv)) { // child process is gone, warn and allow actor to clean up normally NS_WARNING("Cache failed to send AddAll response."); } return true; } mFetchPutList.AppendElement(fetchPut.forget()); @@ -255,17 +251,17 @@ CacheParent::OnCacheKeys(RequestId aRequ if (!SendKeysResponse(aRequestId, aRv, requests.SendAsRequestList())) { // child process is gone, warn and allow actor to clean up normally NS_WARNING("Cache failed to send Keys response."); } } void -CacheParent::OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, const ErrorResult& aRv) +CacheParent::OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, nsresult aRv) { aFetchPut->ClearListener(); mFetchPutList.RemoveElement(aFetchPut); if (!SendAddAllResponse(aRequestId, aRv)) { // child process is gone, warn and allow actor to clean up normally NS_WARNING("Cache failed to send AddAll response."); } }
--- a/dom/cache/CacheParent.h +++ b/dom/cache/CacheParent.h @@ -65,17 +65,17 @@ private: virtual void OnCacheDelete(RequestId aRequestId, nsresult aRv, bool aSuccess) override; virtual void OnCacheKeys(RequestId aRequestId, nsresult aRv, const nsTArray<SavedRequest>& aSavedRequests, StreamList* aStreamList) override; // FetchPut::Listener methods virtual void OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, - const mozilla::ErrorResult& aRv) override; + nsresult aRv) override; already_AddRefed<nsIInputStream> DeserializeCacheStream(const PCacheReadStreamOrVoid& aStreamOrVoid); nsRefPtr<cache::Manager> mManager; const CacheId mCacheId; nsTArray<nsRefPtr<FetchPut>> mFetchPutList; };
--- a/dom/cache/DBSchema.cpp +++ b/dom/cache/DBSchema.cpp @@ -939,19 +939,19 @@ DBSchema::MatchByVaryHeader(mozIStorageC // Extract the header names inside the Vary header value. nsAutoCString varyValue(varyValues[i]); char* rawBuffer = varyValue.BeginWriting(); char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer); bool bailOut = false; for (; token; token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) { nsDependentCString header(token); - MOZ_ASSERT(!header.EqualsLiteral("*"), - "We should have already caught this in " - "TypeUtils::ToPCacheResponseWithoutBody()"); + if (header.EqualsLiteral("*")) { + continue; + } ErrorResult errorResult; nsAutoCString queryValue; queryHeaders->Get(header, queryValue, errorResult); if (errorResult.Failed()) { errorResult.ClearMessage(); MOZ_ASSERT(queryValue.IsEmpty()); }
--- a/dom/cache/FetchPut.cpp +++ b/dom/cache/FetchPut.cpp @@ -131,16 +131,17 @@ FetchPut::FetchPut(Listener* aListener, const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams) : mListener(aListener) , mManager(aManager) , mRequestId(aRequestId) , mCacheId(aCacheId) , mInitiatingThread(NS_GetCurrentThread()) , mStateList(aRequests.Length()) , mPendingCount(0) + , mResult(NS_OK) { MOZ_ASSERT(mListener); MOZ_ASSERT(mManager); MOZ_ASSERT(aRequests.Length() == aRequestStreams.Length()); for (uint32_t i = 0; i < aRequests.Length(); ++i) { State* s = mStateList.AppendElement(); s->mPCacheRequest = aRequests[i]; @@ -151,17 +152,16 @@ FetchPut::FetchPut(Listener* aListener, } FetchPut::~FetchPut() { MOZ_ASSERT(mInitiatingThread == NS_GetCurrentThread()); MOZ_ASSERT(!mListener); mManager->RemoveListener(this); mManager->ReleaseCacheId(mCacheId); - mResult.ClearMessage(); // This may contain a TypeError. } nsresult FetchPut::DispatchToMainThread() { MOZ_ASSERT(!mRunnable); nsCOMPtr<nsIRunnable> runnable = new Runnable(this); @@ -244,30 +244,30 @@ FetchPut::DoFetchOnMainThread() } void FetchPut::FetchComplete(FetchObserver* aObserver, InternalResponse* aInternalResponse) { MOZ_ASSERT(NS_IsMainThread()); - if (aInternalResponse->IsError() && !mResult.Failed()) { + if (aInternalResponse->IsError() && NS_SUCCEEDED(mResult)) { MaybeSetError(NS_ERROR_FAILURE); } for (uint32_t i = 0; i < mStateList.Length(); ++i) { if (mStateList[i].mFetchObserver == aObserver) { ErrorResult rv; ToPCacheResponseWithoutBody(mStateList[i].mPCacheResponse, *aInternalResponse, rv); if (rv.Failed()) { - mResult = Move(rv); - } else { - aInternalResponse->GetBody(getter_AddRefs(mStateList[i].mResponseStream)); + MaybeSetError(rv.ErrorCode()); + return; } + aInternalResponse->GetBody(getter_AddRefs(mStateList[i].mResponseStream)); mStateList[i].mFetchObserver = nullptr; MOZ_ASSERT(mPendingCount > 0); mPendingCount -= 1; MaybeCompleteOnMainThread(); return; } } @@ -286,17 +286,17 @@ FetchPut::MaybeCompleteOnMainThread() DispatchToInitiatingThread(); } void FetchPut::DoPutOnWorkerThread() { MOZ_ASSERT(mInitiatingThread == NS_GetCurrentThread()); - if (mResult.Failed()) { + if (NS_FAILED(mResult)) { MaybeNotifyListener(); return; } // These allocate ~4.5k combined on the stack nsAutoTArray<CacheRequestResponse, 16> putList; nsAutoTArray<nsCOMPtr<nsIInputStream>, 16> requestStreamList; nsAutoTArray<nsCOMPtr<nsIInputStream>, 16> responseStreamList; @@ -372,19 +372,19 @@ FetchPut::MatchInPutList(const PCacheReq // Extract the header names inside the Vary header value. nsAutoCString varyValue(varyHeaders[j]); char* rawBuffer = varyValue.BeginWriting(); char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer); bool bailOut = false; for (; token; token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) { nsDependentCString header(token); - MOZ_ASSERT(!header.EqualsLiteral("*"), - "We should have already caught this in " - "TypeUtils::ToPCacheResponseWithoutBody()"); + if (header.EqualsLiteral("*")) { + continue; + } ErrorResult headerRv; nsAutoCString value; requestHeaders->Get(header, value, headerRv); if (NS_WARN_IF(headerRv.Failed())) { headerRv.ClearMessage(); MOZ_ASSERT(value.IsEmpty()); } @@ -423,31 +423,30 @@ FetchPut::OnCachePutAll(RequestId aReque MOZ_ASSERT(mInitiatingThread == NS_GetCurrentThread()); MaybeSetError(aRv); MaybeNotifyListener(); } void FetchPut::MaybeSetError(nsresult aRv) { - if (mResult.Failed() || NS_SUCCEEDED(aRv)) { + if (NS_FAILED(mResult) || NS_SUCCEEDED(aRv)) { return; } - mResult.Throw(aRv); + mResult = aRv; } void FetchPut::MaybeNotifyListener() { MOZ_ASSERT(mInitiatingThread == NS_GetCurrentThread()); if (!mListener) { return; } mListener->OnFetchPut(this, mRequestId, mResult); - mResult.ClearMessage(); // This may contain a TypeError. } nsIGlobalObject* FetchPut::GetGlobalObject() const { MOZ_CRASH("No global object in parent-size FetchPut operation!"); }
--- a/dom/cache/FetchPut.h +++ b/dom/cache/FetchPut.h @@ -4,17 +4,16 @@ * 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/. */ #ifndef mozilla_dom_cache_FetchPut_h #define mozilla_dom_cache_FetchPut_h #include "mozilla/AlreadyAddRefed.h" #include "mozilla/Attributes.h" -#include "mozilla/ErrorResult.h" #include "mozilla/dom/cache/Manager.h" #include "mozilla/dom/cache/PCacheTypes.h" #include "mozilla/dom/cache/Types.h" #include "mozilla/dom/cache/TypeUtils.h" #include "nsRefPtr.h" #include "nsTArray.h" #include <utility> @@ -35,17 +34,17 @@ class FetchPut final : public Manager::L { public: typedef std::pair<nsRefPtr<Request>, nsRefPtr<Response>> PutPair; class Listener { public: virtual void - OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, const ErrorResult& aRv) = 0; + OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, nsresult aRv) = 0; }; static nsresult Create(Listener* aListener, Manager* aManager, RequestId aRequestId, CacheId aCacheId, const nsTArray<PCacheRequest>& aRequests, const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams, FetchPut** aFetchPutOut); @@ -100,17 +99,17 @@ private: Listener* mListener; nsRefPtr<Manager> mManager; const RequestId mRequestId; const CacheId mCacheId; nsCOMPtr<nsIThread> mInitiatingThread; nsTArray<State> mStateList; uint32_t mPendingCount; - ErrorResult mResult; + nsresult mResult; nsCOMPtr<nsIRunnable> mRunnable; public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::dom::cache::FetchPut) }; } // namespace cache } // namespace dom
--- a/dom/cache/PCache.ipdl +++ b/dom/cache/PCache.ipdl @@ -6,17 +6,16 @@ include protocol PBackground; include protocol PCachePushStream; include PCacheTypes; include protocol PFileDescriptorSet; include protocol PBlob; // FIXME: bug 792908 include protocol PCacheStreamControl; using mozilla::dom::cache::RequestId from "mozilla/dom/cache/Types.h"; -using mozilla::ErrorResult from "ipc/ErrorIPCUtils.h"; include "mozilla/dom/cache/IPCUtils.h"; namespace mozilla { namespace dom { namespace cache { protocol PCache { @@ -31,17 +30,17 @@ parent: AddAll(RequestId requestId, PCacheRequest[] requests); Put(RequestId requestId, CacheRequestResponse aPut); Delete(RequestId requestId, PCacheRequest request, PCacheQueryParams params); Keys(RequestId requestId, PCacheRequestOrVoid request, PCacheQueryParams params); child: MatchResponse(RequestId requestId, nsresult aRv, PCacheResponseOrVoid aResponse); MatchAllResponse(RequestId requestId, nsresult aRv, PCacheResponse[] responses); - AddAllResponse(RequestId requestId, ErrorResult aRv); + AddAllResponse(RequestId requestId, nsresult aRv); PutResponse(RequestId requestId, nsresult aRv); DeleteResponse(RequestId requestId, nsresult aRv, bool success); KeysResponse(RequestId requestId, nsresult aRv, PCacheRequest[] requests); both: __delete__(); };
--- a/dom/cache/TypeUtils.cpp +++ b/dom/cache/TypeUtils.cpp @@ -21,18 +21,16 @@ #include "mozilla/ipc/InputStreamUtils.h" #include "nsCOMPtr.h" #include "nsIAsyncInputStream.h" #include "nsIAsyncOutputStream.h" #include "nsIIPCSerializableInputStream.h" #include "nsStreamUtils.h" #include "nsString.h" #include "nsURLParsers.h" -#include "nsCRT.h" -#include "nsHttp.h" namespace { using mozilla::ErrorResult; using mozilla::unused; using mozilla::void_t; using mozilla::dom::cache::PCacheReadStream; using mozilla::ipc::BackgroundChild; @@ -101,39 +99,16 @@ ProcessURL(nsAString& aUrl, bool* aSchem // ParsePath gives us query position relative to the start of the path queryPos += pathPos; // We want everything before the query sine we already removed the trailing // fragment *aUrlWithoutQueryOut = Substring(aUrl, 0, queryPos - 1); } -static bool -HasVaryStar(mozilla::dom::InternalHeaders* aHeaders) -{ - nsAutoTArray<nsCString, 16> varyHeaders; - ErrorResult rv; - aHeaders->GetAll(NS_LITERAL_CSTRING("vary"), varyHeaders, rv); - MOZ_ALWAYS_TRUE(!rv.Failed()); - - for (uint32_t i = 0; i < varyHeaders.Length(); ++i) { - nsAutoCString varyValue(varyHeaders[i]); - char* rawBuffer = varyValue.BeginWriting(); - char* token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer); - for (; token; - token = nsCRT::strtok(rawBuffer, NS_HTTP_HEADER_SEPS, &rawBuffer)) { - nsDependentCString header(token); - if (header.EqualsLiteral("*")) { - return true; - } - } - } - return false; -} - void SerializeNormalStream(nsIInputStream* aStream, PCacheReadStream& aReadStreamOut) { nsAutoTArray<FileDescriptor, 4> fds; SerializeInputStream(aStream, aReadStreamOut.params(), fds); PFileDescriptorSetChild* fdSet = nullptr; if (!fds.IsEmpty()) { @@ -286,38 +261,31 @@ TypeUtils::ToPCacheResponseWithoutBody(P return; } } aOut.status() = aIn.GetStatus(); aOut.statusText() = aIn.GetStatusText(); nsRefPtr<InternalHeaders> headers = aIn.UnfilteredHeaders(); MOZ_ASSERT(headers); - if (HasVaryStar(headers)) { - aRv.ThrowTypeError(MSG_RESPONSE_HAS_VARY_STAR); - return; - } headers->GetPHeaders(aOut.headers()); aOut.headersGuard() = headers->Guard(); aOut.securityInfo() = aIn.GetSecurityInfo(); } void TypeUtils::ToPCacheResponse(PCacheResponse& aOut, Response& aIn, ErrorResult& aRv) { if (aIn.BodyUsed()) { aRv.ThrowTypeError(MSG_FETCH_BODY_CONSUMED_ERROR); return; } nsRefPtr<InternalResponse> ir = aIn.GetInternalResponse(); ToPCacheResponseWithoutBody(aOut, *ir, aRv); - if (NS_WARN_IF(aRv.Failed())) { - return; - } nsCOMPtr<nsIInputStream> stream; aIn.GetBody(getter_AddRefs(stream)); if (stream) { aIn.SetBodyUsed(); } SerializeCacheStream(stream, &aOut.body(), aRv);
--- a/dom/cache/test/mochitest/test_cache_match_vary.js +++ b/dom/cache/test/mochitest/test_cache_match_vary.js @@ -102,69 +102,25 @@ function testBasicKeys() { return test.cache.keys(new Request(requestURL, {headers: {"Cookie": "foo=bar"}}), {ignoreVary: true}); }).then(function(r) { return checkRequest(r); }); } function testStar() { - function ensurePromiseRejected(promise) { - return promise - .then(function() { - ok(false, "Promise should be rejected"); - }, function(err) { - is(err.name, "TypeError", "Attempting to store a Response with a Vary:* header must fail"); - }); - } var test; - return new Promise(function(resolve, reject) { - var cache; - caches.open(name).then(function(c) { - cache = c; - Promise.all([ - ensurePromiseRejected( - cache.add(new Request(requestURL + "1", {headers: {"WhatToVary": "*"}}))), - ensurePromiseRejected( - cache.addAll([ - new Request(requestURL + "2", {headers: {"WhatToVary": "*"}}), - requestURL + "3", - ])), - ensurePromiseRejected( - fetch(new Request(requestURL + "4", {headers: {"WhatToVary": "*"}})) - .then(function(response) { - return cache.put(requestURL + "4", response); - })), - ensurePromiseRejected( - cache.add(new Request(requestURL + "5", {headers: {"WhatToVary": "*,User-Agent"}}))), - ensurePromiseRejected( - cache.addAll([ - new Request(requestURL + "6", {headers: {"WhatToVary": "*,User-Agent"}}), - requestURL + "7", - ])), - ensurePromiseRejected( - fetch(new Request(requestURL + "8", {headers: {"WhatToVary": "*,User-Agent"}})) - .then(function(response) { - return cache.put(requestURL + "8", response); - })), - ensurePromiseRejected( - cache.add(new Request(requestURL + "9", {headers: {"WhatToVary": "User-Agent,*"}}))), - ensurePromiseRejected( - cache.addAll([ - new Request(requestURL + "10", {headers: {"WhatToVary": "User-Agent,*"}}), - requestURL + "10", - ])), - ensurePromiseRejected( - fetch(new Request(requestURL + "11", {headers: {"WhatToVary": "User-Agent,*"}})) - .then(function(response) { - return cache.put(requestURL + "11", response); - })), - ]).then(reject, resolve); + return setupTest({"WhatToVary": "*", "Cookie": "foo=bar"}) + .then(function(t) { + test = t; + // Ensure that searching with a different Cookie header with Vary:* succeeds. + return test.cache.match(new Request(requestURL, {headers: {"Cookie": "bar=baz"}})); + }).then(function(r) { + return checkResponse(r, test.response, test.responseText); }); - }); } function testMatch() { var test; return setupTest({"WhatToVary": "Cookie", "Cookie": "foo=bar"}) .then(function(t) { test = t; // Ensure that searching with a different Cookie header fails. @@ -173,16 +129,33 @@ function testMatch() { is(typeof r, "undefined", "Searching for a request with a non-matching Cookie header should not succeed"); // Ensure that searching with the same Cookie header succeeds. return test.cache.match(new Request(requestURL, {headers: {"Cookie": "foo=bar"}})); }).then(function(r) { return checkResponse(r, test.response, test.responseText); }); } +function testStarAndAnotherHeader() { + var test; + return setupTest({"WhatToVary": "*,User-Agent"}) + .then(function(t) { + test = t; + // Ensure that searching with a different User-Agent header fails. + return test.cache.match(new Request(requestURL, {headers: {"User-Agent": "MyUA"}})); + }).then(function(r) { + is(typeof r, "undefined", "Searching for a request with a non-matching User-Agent header should not succeed"); + // Ensure that searching with a different User-Agent header but with ignoreVary succeeds. + return test.cache.match(new Request(requestURL, {headers: {"User-Agent": "MyUA"}}), + {ignoreVary: true}); + }).then(function(r) { + return checkResponse(r, test.response, test.responseText); + }); +} + function testInvalidHeaderName() { var test; return setupTest({"WhatToVary": "Foo/Bar, User-Agent"}) .then(function(t) { test = t; // Ensure that searching with a different User-Agent header fails. return test.cache.match(new Request(requestURL, {headers: {"User-Agent": "MyUA"}})); }).then(function(r) { @@ -307,28 +280,28 @@ function testMultipleCacheEntries() { ]); }); } // Make sure to clean up after each test step. function step(testPromise) { return testPromise.then(function() { caches.delete(name); - }, function() { - caches.delete(name); }); } step(testBasics()).then(function() { return step(testBasicKeys()); }).then(function() { return step(testStar()); }).then(function() { return step(testMatch()); }).then(function() { + return step(testStarAndAnotherHeader()); +}).then(function() { return step(testInvalidHeaderName()); }).then(function() { return step(testMultipleHeaders()); }).then(function() { return step(testMultipleCacheEntries()); }).then(function() { testDone(); });