WebKit Bugzilla
Attachment 349280 Details for
Bug 189458
: [Payment Request] Use JSValueInWrappedObject for PaymentResponse's details attribute
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-189458-20180908204318.patch (text/plain), 21.13 KB, created by
Andy Estes
on 2018-09-08 20:43:19 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Andy Estes
Created:
2018-09-08 20:43:19 PDT
Size:
21.13 KB
patch
obsolete
>Subversion Revision: 235833 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 8375217f8686e250bb3a23429f0200fb573ffe7e..bb59549954cda9c0849152b0aedeba9c70fb9123 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,46 @@ >+2018-09-08 Andy Estes <aestes@apple.com> >+ >+ [Payment Request] Use JSValueInWrappedObject for PaymentResponse's details attribute >+ https://bugs.webkit.org/show_bug.cgi?id=189458 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Test: http/tests/paymentrequest/payment-response-reference-cycle-leak.https.html >+ >+ * Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp: >+ (WebCore::ApplePayPaymentHandler::didAuthorizePayment): >+ >+ Created a PaymentResponse::DetailsFunction that converts the ApplePayPayment into a JSValue. >+ >+ * Modules/paymentrequest/PaymentRequest.cpp: >+ (WebCore::PaymentRequest::accept): >+ >+ Passed detailsFunction into PaymentResponse::create(). >+ >+ * Modules/paymentrequest/PaymentRequest.h: >+ * Modules/paymentrequest/PaymentResponse.cpp: >+ (WebCore::PaymentResponse::PaymentResponse): >+ * Modules/paymentrequest/PaymentResponse.h: >+ * Modules/paymentrequest/PaymentResponse.idl: >+ >+ Removed m_details and replaced it with a DetailsFunction and a cached JSValueInWrappedObject. >+ JSPaymentResponseCustom.cpp uses these values to implement the details attribute getter. >+ >+ * Sources.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * bindings/js/JSPaymentResponseCustom.cpp: Added. >+ (WebCore::JSPaymentResponse::details const): >+ >+ Called PaymentResponse::detailsFunction() to cache a JSValue for the details attribute. >+ >+ (WebCore::JSPaymentResponse::visitAdditionalChildren): >+ >+ Visited PaymentResponse::cachedDetails(). >+ >+ * bindings/js/JSServiceWorkerClientCustom.cpp: >+ >+ Fixed a missing include issue that cropped up due to unified source shuffling. >+ > 2018-09-08 Andy Estes <aestes@apple.com> > > [Apple Pay] Dispatch a paymentmethodchange event when the payment method changes >diff --git a/Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp b/Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp >index 46ebd0f05a59992a53e70f574c73ae71e985e687..78312a496f9bd3f7f54d8185686c3584cd02677a 100644 >--- a/Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp >+++ b/Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp >@@ -453,9 +453,12 @@ void ApplePayPaymentHandler::didAuthorizePayment(const Payment& payment) > ASSERT(!m_isUpdating); > > auto applePayPayment = payment.toApplePayPayment(version()); >- auto details = toJSDictionary(*document().execState(), applePayPayment); >- const auto& shippingContact = applePayPayment.shippingContact.value_or(ApplePayPaymentContact()); >- m_paymentRequest->accept(WTF::get<URL>(m_identifier).string(), WTFMove(details), convert(shippingContact), shippingContact.localizedName, shippingContact.emailAddress, shippingContact.phoneNumber); >+ auto shippingContact = applePayPayment.shippingContact.value_or(ApplePayPaymentContact()); >+ auto detailsFunction = [applePayPayment = WTFMove(applePayPayment)](JSC::ExecState& execState) { >+ return toJSDictionary(execState, applePayPayment); >+ }; >+ >+ m_paymentRequest->accept(WTF::get<URL>(m_identifier).string(), WTFMove(detailsFunction), convert(shippingContact), shippingContact.localizedName, shippingContact.emailAddress, shippingContact.phoneNumber); > } > > void ApplePayPaymentHandler::didSelectShippingMethod(const ApplePaySessionPaymentRequest::ShippingMethod& shippingMethod) >diff --git a/Source/WebCore/Modules/paymentrequest/PaymentRequest.cpp b/Source/WebCore/Modules/paymentrequest/PaymentRequest.cpp >index 6e3181f07f1000233e2d0b158f9d727f0df34e69..f3f9656c14003b2bb515774718911bc575ba775c 100644 >--- a/Source/WebCore/Modules/paymentrequest/PaymentRequest.cpp >+++ b/Source/WebCore/Modules/paymentrequest/PaymentRequest.cpp >@@ -42,7 +42,6 @@ > #include "PaymentMethodData.h" > #include "PaymentOptions.h" > #include "PaymentRequestUpdateEvent.h" >-#include "PaymentResponse.h" > #include "ScriptController.h" > #include <JavaScriptCore/JSONObject.h> > #include <JavaScriptCore/ThrowScope.h> >@@ -683,14 +682,13 @@ void PaymentRequest::whenDetailsSettled(std::function<void()>&& callback) > }); > } > >-void PaymentRequest::accept(const String& methodName, JSC::Strong<JSC::JSObject>&& details, Ref<PaymentAddress>&& shippingAddress, const String& payerName, const String& payerEmail, const String& payerPhone) >+void PaymentRequest::accept(const String& methodName, PaymentResponse::DetailsFunction&& detailsFunction, Ref<PaymentAddress>&& shippingAddress, const String& payerName, const String& payerEmail, const String& payerPhone) > { > ASSERT(m_state == State::Interactive); > >- auto response = PaymentResponse::create(*this); >+ auto response = PaymentResponse::create(*this, WTFMove(detailsFunction)); > response->setRequestId(m_details.id); > response->setMethodName(methodName); >- response->setDetails(WTFMove(details)); > > if (m_options.requestShipping) { > response->setShippingAddress(shippingAddress.ptr()); >diff --git a/Source/WebCore/Modules/paymentrequest/PaymentRequest.h b/Source/WebCore/Modules/paymentrequest/PaymentRequest.h >index e532a60b2ae8de66681006e08625a3d5f086a08e..8ef8c089189d595c55d34f02968dcafadc3b91db 100644 >--- a/Source/WebCore/Modules/paymentrequest/PaymentRequest.h >+++ b/Source/WebCore/Modules/paymentrequest/PaymentRequest.h >@@ -34,6 +34,7 @@ > #include "PaymentDetailsInit.h" > #include "PaymentMethodChangeEvent.h" > #include "PaymentOptions.h" >+#include "PaymentResponse.h" > #include "URL.h" > #include <wtf/Variant.h> > >@@ -91,7 +92,7 @@ public: > void paymentMethodChanged(const String& methodName, PaymentMethodChangeEvent::MethodDetailsFunction&&); > ExceptionOr<void> updateWith(UpdateReason, Ref<DOMPromise>&&); > ExceptionOr<void> completeMerchantValidation(Event&, Ref<DOMPromise>&&); >- void accept(const String& methodName, JSC::Strong<JSC::JSObject>&& details, Ref<PaymentAddress>&& shippingAddress, const String& payerName, const String& payerEmail, const String& payerPhone); >+ void accept(const String& methodName, PaymentResponse::DetailsFunction&&, Ref<PaymentAddress>&& shippingAddress, const String& payerName, const String& payerEmail, const String& payerPhone); > void complete(std::optional<PaymentComplete>&&); > void cancel(); > >diff --git a/Source/WebCore/Modules/paymentrequest/PaymentResponse.cpp b/Source/WebCore/Modules/paymentrequest/PaymentResponse.cpp >index 0f16d6f859ce30ba23cef6ed47bb413e5070e1ec..8287d7bb2940255bd2c6736960591fea1bccb5e9 100644 >--- a/Source/WebCore/Modules/paymentrequest/PaymentResponse.cpp >+++ b/Source/WebCore/Modules/paymentrequest/PaymentResponse.cpp >@@ -34,9 +34,11 @@ > > namespace WebCore { > >-PaymentResponse::PaymentResponse(PaymentRequest& request) >+PaymentResponse::PaymentResponse(PaymentRequest& request, DetailsFunction&& detailsFunction) > : m_request { request } >+ , m_detailsFunction { WTFMove(detailsFunction) } > { >+ ASSERT(m_detailsFunction); > } > > PaymentResponse::~PaymentResponse() = default; >diff --git a/Source/WebCore/Modules/paymentrequest/PaymentResponse.h b/Source/WebCore/Modules/paymentrequest/PaymentResponse.h >index 9609b8de9f8007b485a10365d5c2b0d683f8df32..449eff0a5202f2da95ab3f3594e134388e118ab3 100644 >--- a/Source/WebCore/Modules/paymentrequest/PaymentResponse.h >+++ b/Source/WebCore/Modules/paymentrequest/PaymentResponse.h >@@ -29,6 +29,7 @@ > > #include "EventTarget.h" > #include "JSDOMPromiseDeferred.h" >+#include "JSValueInWrappedObject.h" > #include "PaymentAddress.h" > #include "PaymentComplete.h" > >@@ -40,9 +41,11 @@ struct PaymentValidationErrors; > > class PaymentResponse final : public RefCounted<PaymentResponse>, public EventTargetWithInlineData { > public: >- static Ref<PaymentResponse> create(PaymentRequest& request) >+ using DetailsFunction = Function<JSC::Strong<JSC::JSObject>(JSC::ExecState&)>; >+ >+ static Ref<PaymentResponse> create(PaymentRequest& request, DetailsFunction&& detailsFunction) > { >- return adoptRef(*new PaymentResponse(request)); >+ return adoptRef(*new PaymentResponse(request, WTFMove(detailsFunction))); > } > > ~PaymentResponse(); >@@ -53,8 +56,8 @@ public: > const String& methodName() const { return m_methodName; } > void setMethodName(const String& methodName) { m_methodName = methodName; } > >- const JSC::Strong<JSC::JSObject>& details() const { return m_details; } >- void setDetails(JSC::Strong<JSC::JSObject>&& details) { m_details = WTFMove(details); } >+ const DetailsFunction& detailsFunction() const { return m_detailsFunction; } >+ JSValueInWrappedObject& cachedDetails() { return m_cachedDetails; } > > PaymentAddress* shippingAddress() const { return m_shippingAddress.get(); } > void setShippingAddress(PaymentAddress* shippingAddress) { m_shippingAddress = shippingAddress; } >@@ -78,7 +81,7 @@ public: > using RefCounted<PaymentResponse>::deref; > > private: >- explicit PaymentResponse(PaymentRequest&); >+ PaymentResponse(PaymentRequest&, DetailsFunction&&); > > // EventTarget > EventTargetInterface eventTargetInterface() const final { return PaymentResponseEventTargetInterfaceType; } >@@ -89,9 +92,8 @@ private: > Ref<PaymentRequest> m_request; > String m_requestId; > String m_methodName; >- // FIXME: The following use of JSC::Strong is incorrect and can lead to storage leaks >- // due to reference cycles; we should use JSValueInWrappedObject instead. >- JSC::Strong<JSC::JSObject> m_details; >+ DetailsFunction m_detailsFunction; >+ JSValueInWrappedObject m_cachedDetails; > RefPtr<PaymentAddress> m_shippingAddress; > String m_shippingOption; > String m_payerName; >diff --git a/Source/WebCore/Modules/paymentrequest/PaymentResponse.idl b/Source/WebCore/Modules/paymentrequest/PaymentResponse.idl >index 7210dd84239e328c30d13e8e07f419c7b3cdd316..8e1532aabd4ea7c3a915dfdc2ae913e4ce6362d3 100644 >--- a/Source/WebCore/Modules/paymentrequest/PaymentResponse.idl >+++ b/Source/WebCore/Modules/paymentrequest/PaymentResponse.idl >@@ -27,13 +27,14 @@ > Conditional=PAYMENT_REQUEST, > EnabledBySetting=PaymentRequest, > Exposed=Window, >+ JSCustomMarkFunction, > SecureContext, > ] interface PaymentResponse : EventTarget { > serializer = { attribute }; > > readonly attribute DOMString requestId; > readonly attribute DOMString methodName; >- readonly attribute object details; >+ [CustomGetter] readonly attribute object details; > readonly attribute PaymentAddress? shippingAddress; > readonly attribute DOMString? shippingOption; > readonly attribute DOMString? payerName; >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index b065ff85f2798d1b1fb64140fe3d371880c5c64c..7801b309938570718d9a774c01542379a2a6dcb9 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -430,6 +430,7 @@ bindings/js/JSNodeIteratorCustom.cpp > bindings/js/JSNodeListCustom.cpp > bindings/js/JSOffscreenCanvasRenderingContext2DCustom.cpp > bindings/js/JSPaymentMethodChangeEventCustom.cpp >+bindings/js/JSPaymentResponseCustom.cpp > bindings/js/JSPerformanceEntryCustom.cpp > bindings/js/JSPerformanceObserverCustom.cpp > bindings/js/JSPluginElementFunctions.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 99c6b6b9d05a3cc44fb979383a15cda6ac43ecd8..9e5aaba8ad4d0bc7193f4e48a60ce960a32f2258 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -10879,6 +10879,7 @@ > A10BB5831484E3A700B2E87A /* RenderSVGRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGRect.h; sourceTree = "<group>"; }; > A10BB5881484E3B300B2E87A /* RenderSVGShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGShape.cpp; sourceTree = "<group>"; }; > A10BB5891484E3B300B2E87A /* RenderSVGShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGShape.h; sourceTree = "<group>"; }; >+ A10D6E942144C99800FDD14D /* JSPaymentResponseCustom.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSPaymentResponseCustom.cpp; sourceTree = "<group>"; }; > A10DBF4618F92317000D70C6 /* PreviewLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreviewLoaderClient.h; sourceTree = "<group>"; }; > A10DC76814747BAB005E2471 /* StyleGridData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleGridData.cpp; sourceTree = "<group>"; }; > A10DC76914747BAB005E2471 /* StyleGridData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleGridData.h; sourceTree = "<group>"; }; >@@ -19943,6 +19944,7 @@ > BCE7B1920D4E86960075A539 /* JSHistoryCustom.cpp */, > 410B7E711045FAB000D8224F /* JSMessageEventCustom.cpp */, > A1677E242144532800A08C34 /* JSPaymentMethodChangeEventCustom.cpp */, >+ A10D6E942144C99800FDD14D /* JSPaymentResponseCustom.cpp */, > A85F22081430377D007CC884 /* JSPopStateEventCustom.cpp */, > BC348BBD0DB7F531004ABAB9 /* JSXMLHttpRequestCustom.cpp */, > ); >diff --git a/Source/WebCore/bindings/js/JSPaymentResponseCustom.cpp b/Source/WebCore/bindings/js/JSPaymentResponseCustom.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..c627f39b02bd501de1ddb756f833b86f57f37847 >--- /dev/null >+++ b/Source/WebCore/bindings/js/JSPaymentResponseCustom.cpp >@@ -0,0 +1,47 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "JSPaymentResponse.h" >+ >+#if ENABLE(PAYMENT_REQUEST) >+ >+namespace WebCore { >+ >+JSC::JSValue JSPaymentResponse::details(JSC::ExecState& state) const >+{ >+ return cachedPropertyValue(state, *this, wrapped().cachedDetails(), [this, &state] { >+ return wrapped().detailsFunction()(state).get(); >+ }); >+} >+ >+void JSPaymentResponse::visitAdditionalChildren(JSC::SlotVisitor& visitor) >+{ >+ wrapped().cachedDetails().visit(visitor); >+} >+ >+} // namespace WebCore >+ >+#endif // ENABLE(PAYMENT_REQUEST) >diff --git a/Source/WebCore/bindings/js/JSServiceWorkerClientCustom.cpp b/Source/WebCore/bindings/js/JSServiceWorkerClientCustom.cpp >index 58eea3db5b6527685217b144d0d25b38af7f7d27..8d4c5aa54eaed7452bcddc40e7a20281867f5000 100644 >--- a/Source/WebCore/bindings/js/JSServiceWorkerClientCustom.cpp >+++ b/Source/WebCore/bindings/js/JSServiceWorkerClientCustom.cpp >@@ -28,6 +28,7 @@ > #if ENABLE(SERVICE_WORKER) > #include "JSServiceWorkerClient.h" > >+#include "JSDOMBinding.h" > #include "JSServiceWorkerWindowClient.h" > > namespace WebCore { >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 9caf072bc0c85baf1ae463b76050a7aa6738a3cd..6e683989b0f9c242dfbd4b66e6f944eccad30fd5 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,14 @@ >+2018-09-08 Andy Estes <aestes@apple.com> >+ >+ [Payment Request] Use JSValueInWrappedObject for PaymentResponse's details attribute >+ https://bugs.webkit.org/show_bug.cgi?id=189458 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * fast/dom/reference-cycle-leaks.html: >+ * http/tests/paymentrequest/payment-response-reference-cycle-leak.https-expected.txt: Added. >+ * http/tests/paymentrequest/payment-response-reference-cycle-leak.https.html: Added. >+ > 2018-09-08 Andy Estes <aestes@apple.com> > > [Apple Pay] Dispatch a paymentmethodchange event when the payment method changes >diff --git a/LayoutTests/fast/dom/reference-cycle-leaks.html b/LayoutTests/fast/dom/reference-cycle-leaks.html >index 6123965c10ffe421d3b32b01faecf88bf103eb85..f71e0d5f9bba6116a1dc0805ac1d86fe378abc07 100644 >--- a/LayoutTests/fast/dom/reference-cycle-leaks.html >+++ b/LayoutTests/fast/dom/reference-cycle-leaks.html >@@ -125,13 +125,8 @@ function createIDBRequestResultCycle() > // Add another property to the result object that references a leak detection node. > } > >-function createPaymentResponseDetailsCycle() >-{ >- // FIXME: Need to write this test and reorganize so it can be asynchronous. >- // Get a PaymentResponse, requires simulating a successful payment. >- // Add a property to the details object that references the PaymentResponse. >- // Add another property to the details object that references a leak detection node. >-} >+// PaymentResponse details reference cycle is tested in >+// http/tests/paymentrequest/payment-response-reference-cycle-leak.https.html. > > function createRTCStatsReportCycle() > { >diff --git a/LayoutTests/http/tests/paymentrequest/payment-response-reference-cycle-leak.https-expected.txt b/LayoutTests/http/tests/paymentrequest/payment-response-reference-cycle-leak.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..256c4da29ea17844367f06b34a57c9c923eea282 >--- /dev/null >+++ b/LayoutTests/http/tests/paymentrequest/payment-response-reference-cycle-leak.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS PaymentResponse should not leak when there is a reference cycle due to the details attribute >+ >diff --git a/LayoutTests/http/tests/paymentrequest/payment-response-reference-cycle-leak.https.html b/LayoutTests/http/tests/paymentrequest/payment-response-reference-cycle-leak.https.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a48334da11ff9d8b057ea8cc06550c3605ddef80 >--- /dev/null >+++ b/LayoutTests/http/tests/paymentrequest/payment-response-reference-cycle-leak.https.html >@@ -0,0 +1,73 @@ >+<!DOCTYPE html> >+<meta charset="utf-8"> >+<title>Test for leaks caused by reference cycles that pass through PaymentResponse</title> >+<script src="/js-test-resources/ui-helper.js"></script> >+<script src="/resources/payment-request.js"></script> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="/resources/js-test.js"></script> >+<body> >+<script> >+async function checkForNodeLeaks(testFunction, underlyingClass) >+{ >+ // Bump this number as high as we need to, to get reproducible results. >+ const repetitions = 40; >+ >+ GCController.collect(); >+ const beforeCount = internals.numberOfLiveNodes(); >+ for (var i = 0; i < repetitions; ++i) >+ await testFunction(); >+ GCController.collect(); >+ const leaks = internals.numberOfLiveNodes() - beforeCount; >+ >+ if (leaks == repetitions) >+ return "leaked"; >+ if (leaks < repetitions / 10) >+ return "did not leak"; >+ return "leaked an unexpected number of nodes: " + leaks + " leaks in " + repetitions + " runs"; >+} >+ >+async function createPaymentResponseDetailsCycle() >+{ >+ const applePay = { >+ supportedMethods: "https://apple.com/apple-pay", >+ data: { >+ version: 2, >+ merchantIdentifier: '', >+ merchantCapabilities: ['supports3DS'], >+ supportedNetworks: ['visa', 'masterCard'], >+ countryCode: 'US', >+ }, >+ }; >+ >+ const details = { >+ total: { >+ label: "Total", >+ amount: { >+ currency: "USD", >+ value: "1.00", >+ }, >+ }, >+ }; >+ >+ const paymentRequest = new PaymentRequest([applePay], details); >+ await activateThen(async () => { >+ const acceptPromise = paymentRequest.show(); >+ internals.mockPaymentCoordinator.acceptPayment(); >+ const result = await acceptPromise; >+ >+ const leakDetectionNode = document.createTextNode(""); >+ const details = result.details; >+ leakDetectionNode.details = details; >+ details.leakDetectionNode = leakDetectionNode; >+ >+ result.complete("success"); >+ }); >+} >+ >+test(async () => { >+ const result = await checkForNodeLeaks(createPaymentResponseDetailsCycle); >+ assert_equals(result, 'did not leak'); >+}, "PaymentResponse should not leak when there is a reference cycle due to the details attribute"); >+ >+</script>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 189458
:
349277
|
349280
|
349283
|
349284
|
349288
|
349290