Changeset 228331 in webkit


Ignore:
Timestamp:
Feb 9, 2018 11:07:28 AM (6 years ago)
Author:
aestes@apple.com
Message:

[Payment Request] Crash in PaymentRequest::canMakePayment() when Apple Pay payment method data is missing required fields
https://bugs.webkit.org/show_bug.cgi?id=182631

Reviewed by Mark Lam.

Source/WebCore:

PaymentRequest::canMakePayment() needs to parse each payment method's serialized data to
determine if it is a supported payment method. If parsing fails by raising an exception, we
intend to skip over that payment method and try the next one. If all payment method data
fail to parse, we resolve the returned promise with false. At no point do we intend to
propagate the parsing exception up to the calling script, however.

Even though we intend to swallow any exceptions from parsing, we failed to clear the
JavaScript VM's exception state. The next time WebCore tries to execute JavaScript, a
release assertion is raised due to seeing an unexpected exception in the VM.

Fix this by using a CatchScope in PaymentRequest::canMakePayment(), and calling
CatchScope::clearException() in the places we intend to swallow exceptions.

Added a test case to http/tests/paymentrequest/payment-request-canmakepayment-method.https.html.

  • Modules/paymentrequest/PaymentRequest.cpp:

(WebCore::PaymentRequest::canMakePayment):

LayoutTests:

  • http/tests/paymentrequest/payment-request-canmakepayment-method.https-expected.txt:
  • http/tests/paymentrequest/payment-request-canmakepayment-method.https.html:
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r228329 r228331  
     12018-02-09  Andy Estes  <aestes@apple.com>
     2
     3        [Payment Request] Crash in PaymentRequest::canMakePayment() when Apple Pay payment method data is missing required fields
     4        https://bugs.webkit.org/show_bug.cgi?id=182631
     5
     6        Reviewed by Mark Lam.
     7
     8        * http/tests/paymentrequest/payment-request-canmakepayment-method.https-expected.txt:
     9        * http/tests/paymentrequest/payment-request-canmakepayment-method.https.html:
     10
    1112018-02-09  Ryan Haddad  <ryanhaddad@apple.com>
    212
  • trunk/LayoutTests/http/tests/paymentrequest/payment-request-canmakepayment-method.https-expected.txt

    r223160 r228331  
    44PASS If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException.
    55PASS If payment method identifier and serialized parts are supported, resolve promise with true.
     6PASS If a payment method identifier is supported but its serialized parts are not, resolve promise with false.
    67PASS If payment method identifier is unknown, resolve promise with false.
    78PASS Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException.
  • trunk/LayoutTests/http/tests/paymentrequest/payment-request-canmakepayment-method.https.html

    r224402 r228331  
    1111<script src="/resources/testharnessreport.js"></script>
    1212<script>
    13     const applePay = Object.freeze({
     13const applePay = Object.freeze({
    1414    supportedMethods: "https://apple.com/apple-pay",
    1515    data: {
     
    1919        supportedNetworks: ["visa", "masterCard"],
    2020        countryCode: "US",
     21    }
     22});
     23const invalidApplePay = Object.freeze({
     24    supportedMethods: "https://apple.com/apple-pay",
     25    data: {
    2126    }
    2227});
     
    99104
    100105promise_test(async t => {
     106  const request = new PaymentRequest([invalidApplePay], defaultDetails);
     107  assert_false(await request.canMakePayment(), "Apple Pay with invalid data should not be supported");
     108}, `If a payment method identifier is supported but its serialized parts are not, resolve promise with false.`);
     109
     110promise_test(async t => {
    101111  const unsupportedMethods = [
    102112    "this-is-not-supported",
  • trunk/Source/WebCore/ChangeLog

    r228327 r228331  
     12018-02-09  Andy Estes  <aestes@apple.com>
     2
     3        [Payment Request] Crash in PaymentRequest::canMakePayment() when Apple Pay payment method data is missing required fields
     4        https://bugs.webkit.org/show_bug.cgi?id=182631
     5
     6        Reviewed by Mark Lam.
     7
     8        PaymentRequest::canMakePayment() needs to parse each payment method's serialized data to
     9        determine if it is a supported payment method. If parsing fails by raising an exception, we
     10        intend to skip over that payment method and try the next one. If all payment method data
     11        fail to parse, we resolve the returned promise with false. At no point do we intend to
     12        propagate the parsing exception up to the calling script, however.
     13
     14        Even though we intend to swallow any exceptions from parsing, we failed to clear the
     15        JavaScript VM's exception state. The next time WebCore tries to execute JavaScript, a
     16        release assertion is raised due to seeing an unexpected exception in the VM.
     17
     18        Fix this by using a CatchScope in PaymentRequest::canMakePayment(), and calling
     19        CatchScope::clearException() in the places we intend to swallow exceptions.
     20
     21        Added a test case to http/tests/paymentrequest/payment-request-canmakepayment-method.https.html.
     22
     23        * Modules/paymentrequest/PaymentRequest.cpp:
     24        (WebCore::PaymentRequest::canMakePayment):
     25
    1262018-02-09  Zalan Bujtas  <zalan@apple.com>
    227
  • trunk/Source/WebCore/Modules/paymentrequest/PaymentRequest.cpp

    r228195 r228331  
    490490    }
    491491
     492    auto scope = DECLARE_CATCH_SCOPE(document.execState()->vm());
    492493    for (auto& paymentMethod : m_serializedMethodData) {
    493494        auto data = parse(document, paymentMethod.serializedData);
    494         if (data.hasException())
     495        ASSERT(!!scope.exception() == data.hasException());
     496        if (data.hasException()) {
     497            scope.clearException();
    495498            continue;
     499        }
    496500
    497501        auto handler = PaymentHandler::create(document, *this, paymentMethod.identifier);
     
    500504
    501505        auto exception = handler->convertData(data.releaseReturnValue());
    502         if (exception.hasException())
     506        ASSERT(!!scope.exception() == exception.hasException());
     507        if (exception.hasException()) {
     508            scope.clearException();
    503509            continue;
     510        }
    504511
    505512        handler->canMakePayment([promise = WTFMove(promise)](bool canMakePayment) mutable {
Note: See TracChangeset for help on using the changeset viewer.