Bug 1572155 - Make validationURL use baseURI r=marcosc
authorKagami Sascha Rosylight <saschanaz@outlook.com>
Tue, 20 Aug 2019 03:45:58 +0000
changeset 489126 6248f85c53133f5a9fb80177e3143357f08d3442
parent 489125 252643ff91c5b12225350e8c02d45e00656f8bb6
child 489127 41e0d5d0947e07439e3ec4c586da782897c35149
push id36465
push userdvarga@mozilla.com
push dateWed, 21 Aug 2019 16:47:43 +0000
treeherdermozilla-central@4ab60925635c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmarcosc
bugs1572155
milestone70.0a1
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
Bug 1572155 - Make validationURL use baseURI r=marcosc Differential Revision: https://phabricator.services.mozilla.com/D41047
dom/payments/MerchantValidationEvent.cpp
dom/payments/MerchantValidationEvent.h
testing/web-platform/tests/payment-request/MerchantValidationEvent/constructor.https.html
--- a/dom/payments/MerchantValidationEvent.cpp
+++ b/dom/payments/MerchantValidationEvent.cpp
@@ -4,23 +4,25 @@
  * 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 "mozilla/dom/MerchantValidationEvent.h"
 #include "nsNetCID.h"
 #include "mozilla/dom/PaymentRequest.h"
 #include "mozilla/dom/Location.h"
 #include "mozilla/dom/URL.h"
+#include "mozilla/ResultExtensions.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_INHERITED(MerchantValidationEvent, Event, mRequest)
+NS_IMPL_CYCLE_COLLECTION_INHERITED(MerchantValidationEvent, Event,
+                                   mValidationURL, mRequest)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MerchantValidationEvent, Event)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MerchantValidationEvent)
 NS_INTERFACE_MAP_END_INHERITING(Event)
 
 NS_IMPL_ADDREF_INHERITED(MerchantValidationEvent, Event)
@@ -38,64 +40,58 @@ already_AddRefed<MerchantValidationEvent
 
 // Internal JS object constructor
 already_AddRefed<MerchantValidationEvent> MerchantValidationEvent::Constructor(
     EventTarget* aOwner, const nsAString& aType,
     const MerchantValidationEventInit& aEventInitDict, ErrorResult& aRv) {
   RefPtr<MerchantValidationEvent> e = new MerchantValidationEvent(aOwner);
   bool trusted = e->Init(aOwner);
   e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable);
-  if (!e->init(aEventInitDict, aRv)) {
+  nsString errMsg;
+  Result<Ok, nsresult> rv = e->init(aEventInitDict, errMsg);
+  if (rv.isErr()) {
+    auto err = rv.unwrapErr();
+    switch (err) {
+      case NS_ERROR_TYPE_ERR:
+        aRv.ThrowRangeError<MSG_ILLEGAL_RANGE_PR_CONSTRUCTOR>(errMsg);
+        break;
+      case NS_ERROR_MALFORMED_URI:
+        aRv.ThrowTypeError<MSG_INVALID_URL>(aEventInitDict.mValidationURL);
+        break;
+      default:
+        aRv.Throw(err);
+        break;
+    }
     return nullptr;
   }
   e->SetTrusted(trusted);
   e->SetComposed(aEventInitDict.mComposed);
   return e.forget();
 }
 
-bool MerchantValidationEvent::init(
-    const MerchantValidationEventInit& aEventInitDict, ErrorResult& aRv) {
+Result<Ok, nsresult> MerchantValidationEvent::init(
+    const MerchantValidationEventInit& aEventInitDict, nsString& errMsg) {
   // Check methodName is valid
   if (!aEventInitDict.mMethodName.IsEmpty()) {
-    nsString errMsg;
-    auto rv = PaymentRequest::IsValidPaymentMethodIdentifier(
+    nsresult rv = PaymentRequest::IsValidPaymentMethodIdentifier(
         aEventInitDict.mMethodName, errMsg);
     if (NS_FAILED(rv)) {
-      aRv.ThrowRangeError<MSG_ILLEGAL_RANGE_PR_CONSTRUCTOR>(errMsg);
-      return false;
+      return Err(rv);
     }
   }
   SetMethodName(aEventInitDict.mMethodName);
   nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetParentObject());
   auto doc = window->GetExtantDoc();
   if (!doc) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
-    return false;
+    return Err(NS_ERROR_UNEXPECTED);
   }
-  auto principal = doc->NodePrincipal();
-
-  nsCOMPtr<nsIURI> baseURI;
-  principal->GetURI(getter_AddRefs(baseURI));
 
-  nsresult rv;
-  nsCOMPtr<nsIURI> validationUri;
-  rv = NS_NewURI(getter_AddRefs(validationUri), aEventInitDict.mValidationURL,
-                 nullptr, baseURI);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aRv.ThrowTypeError<MSG_INVALID_URL>(aEventInitDict.mValidationURL);
-    return false;
-  }
-  nsAutoCString utf8href;
-  rv = validationUri->GetSpec(utf8href);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(NS_ERROR_DOM_BAD_URI);
-    return false;
-  }
-  CopyUTF8toUTF16(utf8href, mValidationURL);
-  return true;
+  MOZ_TRY_VAR(mValidationURL,
+              doc->ResolveWithBaseURI(aEventInitDict.mValidationURL));
+  return Ok();
 }
 
 MerchantValidationEvent::MerchantValidationEvent(EventTarget* aOwner)
     : Event(aOwner, nullptr, nullptr), mWaitForUpdate(false) {
   MOZ_ASSERT(aOwner);
 }
 
 void MerchantValidationEvent::ResolvedCallback(JSContext* aCx,
@@ -156,32 +152,32 @@ void MerchantValidationEvent::SetRequest
   MOZ_ASSERT(IsTrusted());
   MOZ_ASSERT(!mRequest);
   MOZ_ASSERT(aRequest);
 
   mRequest = aRequest;
 }
 
 void MerchantValidationEvent::GetValidationURL(nsAString& aValidationURL) {
-  aValidationURL.Assign(mValidationURL);
-}
-
-void MerchantValidationEvent::SetValidationURL(nsAString& aValidationURL) {
-  mValidationURL.Assign(aValidationURL);
+  nsAutoCString utf8href;
+  nsresult rv = mValidationURL->GetSpec(utf8href);
+  MOZ_ASSERT(NS_SUCCEEDED(rv));
+  Unused << rv;
+  aValidationURL.Assign(NS_ConvertUTF8toUTF16(utf8href));
 }
 
 void MerchantValidationEvent::GetMethodName(nsAString& aMethodName) {
   aMethodName.Assign(mMethodName);
 }
 
 void MerchantValidationEvent::SetMethodName(const nsAString& aMethodName) {
   mMethodName.Assign(aMethodName);
 }
 
-MerchantValidationEvent::~MerchantValidationEvent() {}
+MerchantValidationEvent::~MerchantValidationEvent() = default;
 
 JSObject* MerchantValidationEvent::WrapObjectInternal(
     JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
   return MerchantValidationEvent_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/payments/MerchantValidationEvent.h
+++ b/dom/payments/MerchantValidationEvent.h
@@ -4,16 +4,17 @@
  * 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_MerchantValidationEvent_h
 #define mozilla_dom_MerchantValidationEvent_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
+#include "mozilla/Result.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/MerchantValidationEventBinding.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
 
 namespace mozilla {
 namespace dom {
 
 class Promise;
@@ -44,31 +45,29 @@ class MerchantValidationEvent : public E
       const MerchantValidationEventInit& aEventInitDict, ErrorResult& aRv);
 
   void Complete(Promise& aPromise, ErrorResult& aRv);
 
   void SetRequest(PaymentRequest* aRequest);
 
   void GetValidationURL(nsAString& aValidationURL);
 
-  void SetValidationURL(nsAString& aValidationURL);
-
   void GetMethodName(nsAString& aMethodName);
 
   void SetMethodName(const nsAString& aMethodName);
 
  protected:
-  bool init(const MerchantValidationEventInit& aEventInitDict,
-            ErrorResult& aRv);
+  Result<Ok, nsresult> init(const MerchantValidationEventInit& aEventInitDict,
+                            nsString& errMsg);
   ~MerchantValidationEvent();
 
  private:
   // Indicating whether an Complete()-initiated update is currently in progress.
   bool mWaitForUpdate;
-  nsString mValidationURL;
+  nsCOMPtr<nsIURI> mValidationURL;
   RefPtr<PaymentRequest> mRequest;
   nsString mMethodName;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_MerchantValidationEvent_h
--- a/testing/web-platform/tests/payment-request/MerchantValidationEvent/constructor.https.html
+++ b/testing/web-platform/tests/payment-request/MerchantValidationEvent/constructor.https.html
@@ -75,16 +75,30 @@ test(() => {
   for (const path of relativePaths) {
     const event = new MerchantValidationEvent("test", { validationURL: path });
     const expected = new URL(path, document.location.href).href;
     assert_equals(event.validationURL, expected);
   }
 }, "Relative validationURLs use the document as the base.");
 
 test(() => {
+  const validationURL = "pass";
+  const base = document.createElement("base");
+  base.href = "https://pass.com";
+  document.head.append(base);
+  const event = new MerchantValidationEvent("test", { validationURL });
+  try {
+    assert_idl_attribute(event, "validationURL");
+    assert_equals(event.validationURL, "https://pass.com/pass");
+  } finally {
+    base.remove();
+  }
+}, "Relative validationURLs use the document.baseURI as the base.");
+
+test(() => {
   const methodName = "https://pass.com";
   const event = new MerchantValidationEvent("test", { methodName });
   assert_idl_attribute(event, "methodName");
   assert_equals(event.methodName, "https://pass.com");
 }, "Must have a methodName IDL attribute, which is initialized with to the methodName dictionary value.");
 
 test(() => {
   const event = new MerchantValidationEvent("test", {});