Changeset 286452 in webkit
- Timestamp:
- Dec 2, 2021 2:21:46 PM (8 months ago)
- Location:
- trunk
- Files:
-
- 13 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/tests/ssl/applepay/PaymentRequest.https-expected.txt (modified) (12 diffs)
-
LayoutTests/http/tests/ssl/applepay/PaymentRequest.https.html (modified) (11 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Modules/applepay-ams-ui/ApplePayAMSUIPaymentHandler.cpp (modified) (2 diffs)
-
Source/WebCore/Modules/applepay-ams-ui/ApplePayAMSUIPaymentHandler.h (modified) (1 diff)
-
Source/WebCore/Modules/applepay/ApplePaySession.cpp (modified) (1 diff)
-
Source/WebCore/Modules/applepay/PaymentRequestValidator.h (modified) (2 diffs)
-
Source/WebCore/Modules/applepay/PaymentRequestValidator.mm (modified) (1 diff)
-
Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp (modified) (4 diffs)
-
Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.h (modified) (1 diff)
-
Source/WebCore/Modules/paymentrequest/PaymentHandler.h (modified) (1 diff)
-
Source/WebCore/Modules/paymentrequest/PaymentRequest.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r286451 r286452 1 2021-12-02 Devin Rousso <drousso@apple.com> 2 3 [Payment Request] Validate payment method data on construction 4 https://bugs.webkit.org/show_bug.cgi?id=233292 5 <rdar://problem/85736007> 6 7 Reviewed by Andy Estes. 8 9 * http/tests/ssl/applepay/PaymentRequest.https.html: 10 * http/tests/ssl/applepay/PaymentRequest.https-expected.txt: 11 1 12 2021-12-02 Fujii Hironori <Hironori.Fujii@sony.com> 2 13 -
trunk/LayoutTests/http/tests/ssl/applepay/PaymentRequest.https-expected.txt
r274012 r286452 11 11 Testing ApplePayRequest.version 12 12 13 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.version = 0; request = new PaymentRequest([paymentMethod], validPaymentDetails()) 14 PASS request.show() rejected promise with InvalidAccessError: "0" is not a supported version.. 15 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.version = 1000; request = new PaymentRequest([paymentMethod], validPaymentDetails()) 16 PASS request.show() rejected promise with InvalidAccessError: "1000" is not a supported version.. 13 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.version = 0; 14 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception InvalidAccessError: "0" is not a supported version.. 15 16 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.version = 1000; 17 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception InvalidAccessError: "1000" is not a supported version.. 18 17 19 18 20 Testing ApplePayRequest.countryCode … … 21 23 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.countryCode is required and must be an instance of DOMString. 22 24 23 24 25 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = undefined; 25 26 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.countryCode is required and must be an instance of DOMString. 26 27 27 28 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 'invalid'; request = new PaymentRequest([paymentMethod], validPaymentDetails()) 29 PASS request.show() rejected promise with TypeError: "invalid" is not a valid country code.. 30 31 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = ''; request = new PaymentRequest([paymentMethod], validPaymentDetails()) 32 PASS request.show() rejected promise with TypeError: "" is not a valid country code.. 33 34 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = null; request = new PaymentRequest([paymentMethod], validPaymentDetails()) 35 PASS request.show() rejected promise with TypeError: "null" is not a valid country code.. 36 37 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 7; request = new PaymentRequest([paymentMethod], validPaymentDetails()) 38 PASS request.show() rejected promise with TypeError: "7" is not a valid country code.. 28 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 'invalid'; 29 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "invalid" is not a valid country code.. 30 31 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = ''; 32 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "" is not a valid country code.. 33 34 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = null; 35 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "null" is not a valid country code.. 36 37 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 7; 38 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "7" is not a valid country code.. 39 39 40 40 41 Testing ApplePayRequest.supportedNetworks … … 43 44 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.supportedNetworks is required and must be an instance of sequence. 44 45 45 46 46 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ''; 47 47 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 48 48 49 50 49 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = null; 51 50 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 52 53 51 54 52 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = undefined; 55 53 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.supportedNetworks is required and must be an instance of sequence. 56 54 57 58 55 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = 7; 59 56 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 60 57 61 62 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = []; request = new PaymentRequest([paymentMethod], validPaymentDetails()) 63 PASS request.show() rejected promise with TypeError: At least one supported network must be provided.. 64 65 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork']; request = new PaymentRequest([paymentMethod], validPaymentDetails()) 66 PASS request.show() rejected promise with TypeError: "invalidNetwork" is not a valid payment network.. 67 68 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork', 'visa']; request = new PaymentRequest([paymentMethod], validPaymentDetails()) 69 PASS request.show() rejected promise with TypeError: "invalidNetwork" is not a valid payment network.. 58 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = []; 59 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: At least one supported network must be provided.. 60 61 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork']; 62 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "invalidNetwork" is not a valid payment network.. 63 64 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork', 'visa']; 65 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: "invalidNetwork" is not a valid payment network.. 66 70 67 71 68 Testing ApplePayRequest.merchantCapabilities … … 74 71 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.merchantCapabilities is required and must be an instance of sequence. 75 72 76 77 73 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = ''; 78 74 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 79 75 80 81 76 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = null; 82 77 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 83 84 78 85 79 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = undefined; 86 80 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Member ApplePayRequest.merchantCapabilities is required and must be an instance of sequence. 87 81 88 89 82 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = 7; 90 83 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 91 84 92 93 85 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = ['invalidCapability']; 94 86 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 95 87 96 97 88 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = ['invalidCapability', 'supports3DS']; 98 89 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 99 90 100 101 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = []; request = new PaymentRequest([paymentMethod], validPaymentDetails()) 102 PASS request.show() rejected promise with TypeError: At least one merchant capability must be provided.. 91 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = []; 92 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: At least one merchant capability must be provided.. 93 103 94 104 95 Testing ApplePayRequest.requiredBillingContactFields … … 107 98 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 108 99 109 110 100 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = null; 111 101 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 112 102 113 114 103 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = 7; 115 104 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 116 105 117 118 106 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = { }; 119 107 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 120 108 121 122 109 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = ['']; 123 110 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 124 111 125 126 112 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [null]; 127 113 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 128 114 129 130 115 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [undefined]; 131 116 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 132 117 133 134 118 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [{}]; 135 119 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 136 120 137 138 121 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = ['invalid']; 139 122 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. … … 145 128 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 146 129 147 148 130 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.billingContact = 7; 149 131 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. … … 155 137 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 156 138 157 158 139 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = null; 159 140 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 160 141 161 162 142 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = 7; 163 143 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Value is not a sequence. 164 144 165 166 145 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = { }; 167 146 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 168 147 169 170 148 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = ['']; 171 149 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 172 150 173 174 151 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [null]; 175 152 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 176 153 177 178 154 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [undefined]; 179 155 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 180 156 181 182 157 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [{}]; 183 158 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 184 159 185 186 160 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = ['invalid']; 187 161 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. … … 192 166 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.shippingContact = ''; 193 167 PASS new PaymentRequest([paymentMethod], validPaymentDetails()) threw exception TypeError: Type error. 194 195 168 196 169 SETUP: paymentMethod = validPaymentMethod(); paymentMethod.data.shippingContact = 7; … … 230 203 PASS new PaymentRequest([validPaymentMethod()], paymentDetails) threw exception RangeError: "" is not a valid currency code.. 231 204 232 233 205 SETUP: paymentDetails = validPaymentDetails(); paymentDetails.total = { label: 'label', amount: { currency: 'USD', value:'-10.00'} }; 234 206 PASS new PaymentRequest([validPaymentMethod()], paymentDetails) threw exception TypeError: Total currency values cannot be negative.. … … 237 209 PASS request.show() rejected promise with TypeError: Total amount is too big.. 238 210 211 239 212 Testing PaymentDetails.displayItems 240 213 … … 274 247 SETUP: paymentDetails = validPaymentDetails(); paymentDetails.displayItems = [{ label: 'label', amount: { currency: 'EUR', value: '10.00' } }]; request = new PaymentRequest([validPaymentMethod()], paymentDetails) 275 248 PASS request.show() rejected promise with TypeError: "EUR" does not match the expected currency of "USD". Apple Pay requires all PaymentCurrencyAmounts to use the same currency code.. 249 250 276 251 Testing PaymentDetails.shippingOptions 277 252 … … 311 286 SETUP: paymentDetails = validPaymentDetails(); paymentDetails.shippingOptions = [{ amount: { currency: 'EUR', value: '10.00' }, id: '', label: '' }]; request = new PaymentRequest([validPaymentMethod()], paymentDetails, {requestShipping: true}) 312 287 PASS request.show() rejected promise with TypeError: "EUR" does not match the expected currency of "USD". Apple Pay requires all PaymentCurrencyAmounts to use the same currency code.. 288 289 313 290 Testing PaymentOptions 314 291 -
trunk/LayoutTests/http/tests/ssl/applepay/PaymentRequest.https.html
r274012 r286452 59 59 debug("Testing ApplePayRequest.version") 60 60 debug("") 61 await logAndShould Reject("paymentMethod = validPaymentMethod(); paymentMethod.data.version = 0; request = new PaymentRequest([paymentMethod], validPaymentDetails())", "request.show()")62 await logAndShould Reject("paymentMethod = validPaymentMethod(); paymentMethod.data.version = 1000; request = new PaymentRequest([paymentMethod], validPaymentDetails())", "request.show()")61 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.version = 0;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 62 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.version = 1000;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 63 63 debug("") 64 64 … … 66 66 debug("") 67 67 await logAndShouldThrow("paymentMethod = validPaymentMethod(); delete paymentMethod.data.countryCode;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 68 debug("")69 68 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = undefined;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 70 debug("") 71 await logAndShouldReject("paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 'invalid'; request = new PaymentRequest([paymentMethod], validPaymentDetails())", "request.show()") 72 debug("") 73 await logAndShouldReject("paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = ''; request = new PaymentRequest([paymentMethod], validPaymentDetails())", "request.show()") 74 debug("") 75 await logAndShouldReject("paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = null; request = new PaymentRequest([paymentMethod], validPaymentDetails())", "request.show()") 76 debug("") 77 await logAndShouldReject("paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 7; request = new PaymentRequest([paymentMethod], validPaymentDetails())", "request.show()") 69 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 'invalid';", "new PaymentRequest([paymentMethod], validPaymentDetails())") 70 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = '';", "new PaymentRequest([paymentMethod], validPaymentDetails())") 71 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = null;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 72 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.countryCode = 7;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 78 73 debug("") 79 74 … … 81 76 debug("") 82 77 await logAndShouldThrow("paymentMethod = validPaymentMethod(); delete paymentMethod.data.supportedNetworks;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 83 debug("")84 78 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = '';", "new PaymentRequest([paymentMethod], validPaymentDetails())") 85 debug("")86 79 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = null;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 87 debug("")88 80 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = undefined;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 89 debug("")90 81 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = 7;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 91 debug("") 92 await logAndShouldReject("paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = []; request = new PaymentRequest([paymentMethod], validPaymentDetails())", "request.show()") 93 debug("") 94 await logAndShouldReject("paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork']; request = new PaymentRequest([paymentMethod], validPaymentDetails())", "request.show()") 95 debug("") 96 await logAndShouldReject("paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork', 'visa']; request = new PaymentRequest([paymentMethod], validPaymentDetails())", "request.show()") 82 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = [];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 83 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork'];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 84 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.supportedNetworks = ['invalidNetwork', 'visa'];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 97 85 debug("") 98 86 … … 100 88 debug(""); 101 89 await logAndShouldThrow("paymentMethod = validPaymentMethod(); delete paymentMethod.data.merchantCapabilities;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 102 debug("")103 90 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = '';", "new PaymentRequest([paymentMethod], validPaymentDetails())") 104 debug("")105 91 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = null;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 106 debug("")107 92 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = undefined;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 108 debug("")109 93 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = 7;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 110 debug("")111 94 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = ['invalidCapability'];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 112 debug("")113 95 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = ['invalidCapability', 'supports3DS'];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 114 debug("") 115 await logAndShouldReject("paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = []; request = new PaymentRequest([paymentMethod], validPaymentDetails())", "request.show()") 96 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.merchantCapabilities = [];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 116 97 debug("") 117 98 … … 119 100 debug("") 120 101 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = '';", "new PaymentRequest([paymentMethod], validPaymentDetails())") 121 debug("")122 102 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = null;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 123 debug("")124 103 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = 7;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 125 debug("")126 104 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = { };", "new PaymentRequest([paymentMethod], validPaymentDetails())") 127 debug("")128 105 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [''];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 129 debug("")130 106 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [null];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 131 debug("")132 107 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [undefined];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 133 debug("")134 108 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = [{}];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 135 debug("")136 109 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredBillingContactFields = ['invalid'];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 137 110 debug("") … … 140 113 debug("") 141 114 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.billingContact = '';", "new PaymentRequest([paymentMethod], validPaymentDetails())") 142 debug("")143 115 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.billingContact = 7;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 144 116 debug("") … … 147 119 debug("") 148 120 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = '';", "new PaymentRequest([paymentMethod], validPaymentDetails())") 149 debug("")150 121 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = null;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 151 debug("")152 122 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = 7;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 153 debug("")154 123 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = { };", "new PaymentRequest([paymentMethod], validPaymentDetails())") 155 debug("")156 124 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [''];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 157 debug("")158 125 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [null];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 159 debug("")160 126 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [undefined];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 161 debug("")162 127 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = [{}];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 163 debug("")164 128 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.requiredShippingContactFields = ['invalid'];", "new PaymentRequest([paymentMethod], validPaymentDetails())") 165 129 debug("") … … 168 132 debug("") 169 133 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.shippingContact = '';", "new PaymentRequest([paymentMethod], validPaymentDetails())") 170 debug("")171 134 await logAndShouldThrow("paymentMethod = validPaymentMethod(); paymentMethod.data.shippingContact = 7;", "new PaymentRequest([paymentMethod], validPaymentDetails())") 172 135 debug("") … … 184 147 await logAndShouldThrow("paymentDetails = validPaymentDetails(); paymentDetails.total = { label: 'label', amount: 'amount' };", "new PaymentRequest([validPaymentMethod()], paymentDetails)") 185 148 await logAndShouldThrow("paymentDetails = validPaymentDetails(); paymentDetails.total = { label: 'label', amount: { currency: '', value: '0' } };", "new PaymentRequest([validPaymentMethod()], paymentDetails)") 186 debug("")187 149 await logAndShouldThrow("paymentDetails = validPaymentDetails(); paymentDetails.total = { label: 'label', amount: { currency: 'USD', value:'-10.00'} };", "new PaymentRequest([validPaymentMethod()], paymentDetails)") 188 150 await logAndShouldReject("paymentDetails = validPaymentDetails(); paymentDetails.total = { label: 'label', amount: { currency: 'USD', value: '10000000000.00' } }; request = new PaymentRequest([validPaymentMethod()], paymentDetails)", "request.show()") 151 debug("") 189 152 debug("") 190 153 … … 203 166 await logAndShouldThrow("paymentDetails = validPaymentDetails(); paymentDetails.displayItems = [{ label: 'label', amount: '10.00', type: 'invalid' }];", "new PaymentRequest([validPaymentMethod()], paymentDetails)") 204 167 await logAndShouldReject("paymentDetails = validPaymentDetails(); paymentDetails.displayItems = [{ label: 'label', amount: { currency: 'EUR', value: '10.00' } }]; request = new PaymentRequest([validPaymentMethod()], paymentDetails)", "request.show()") 168 debug("") 169 debug("") 205 170 206 171 debug("Testing PaymentDetails.shippingOptions") … … 218 183 await logAndShouldThrow("paymentDetails = validPaymentDetails(); paymentDetails.shippingOptions = [{ amount: '-1', detail: '', identifier: '', label: '' }];", "new PaymentRequest([validPaymentMethod()], paymentDetails, {requestShipping: true})") 219 184 await logAndShouldReject("paymentDetails = validPaymentDetails(); paymentDetails.shippingOptions = [{ amount: { currency: 'EUR', value: '10.00' }, id: '', label: '' }]; request = new PaymentRequest([validPaymentMethod()], paymentDetails, {requestShipping: true})", "request.show()") 185 debug("") 186 debug("") 220 187 221 188 debug("Testing PaymentOptions") -
trunk/Source/WebCore/ChangeLog
r286449 r286452 1 2021-12-02 Devin Rousso <drousso@apple.com> 2 3 [Payment Request] Validate payment method data on construction 4 https://bugs.webkit.org/show_bug.cgi?id=233292 5 <rdar://problem/85736007> 6 7 Reviewed by Andy Estes. 8 9 This will allow developers to replace any `ApplePaySession.supportsVersion` check(s) by 10 attempting to create a `PaymentRequest` object with data specific to Apple Pay. This is 11 actually an improvement, because it'll also allow developers to catch most errors in that 12 data earlier, as previously any errors would only be thrown when `show()` is called. 13 14 Spec: <https://github.com/w3c/payment-request/pull/976> 15 16 Test: http/tests/ssl/applepay/PaymentRequest.https.html 17 18 * Modules/paymentrequest/PaymentRequest.cpp: 19 (WebCore::PaymentRequest::show): 20 * Modules/paymentrequest/PaymentHandler.h: 21 Adjust `PaymentHandler::convertData` to take a `Document` so that additional validation 22 can be performed on the provided payment method(s) (e.g. check the Apple Pay version). 23 24 * Modules/applepay/PaymentRequestValidator.h: 25 * Modules/applepay/PaymentRequestValidator.mm: 26 (WebCore::PaymentRequestValidator::validate): 27 Allow callers to choose what fields to validate. This is needed because when the 28 `ApplePaySessionPaymentRequest` created/converted when validating the payment method data in 29 the `PaymentRequest` constructor isn't able to get fields from the `PaymentRequest` as it 30 hasn't been created yet. 31 32 * Modules/applepay/ApplePaySession.cpp: 33 (WebCore::convertAndValidate): 34 * Modules/applepay/paymentrequest/ApplePayPaymentHandler.h: 35 * Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp: 36 (WebCore::convertAndValidateApplePayRequest): 37 (WebCore::ApplePayPaymentHandler::convertData): 38 (WebCore::ApplePayPaymentHandler::show): 39 * Modules/applepay-ams-ui/ApplePayAMSUIPaymentHandler.h: 40 * Modules/applepay-ams-ui/ApplePayAMSUIPaymentHandler.cpp: 41 (WebCore::convertAndValidateApplePayAMSUIRequest): 42 (WebCore::ApplePayAMSUIPaymentHandler::convertData): 43 1 44 2021-12-02 Brandon Stewart <brandonstewart@apple.com> 2 45 -
trunk/Source/WebCore/Modules/applepay-ams-ui/ApplePayAMSUIPaymentHandler.cpp
r285444 r286452 37 37 namespace WebCore { 38 38 39 static ExceptionOr<ApplePayAMSUIRequest> convertAndValidateApplePayAMSUIRequest( ScriptExecutionContext& context, JSC::JSValue data)39 static ExceptionOr<ApplePayAMSUIRequest> convertAndValidateApplePayAMSUIRequest(Document& document, JSC::JSValue data) 40 40 { 41 41 if (data.isEmpty()) 42 42 return Exception { TypeError, "Missing payment method data." }; 43 43 44 auto throwScope = DECLARE_THROW_SCOPE( context.vm());45 auto applePayAMSUIRequest = convertDictionary<ApplePayAMSUIRequest>(* context.globalObject(), data);44 auto throwScope = DECLARE_THROW_SCOPE(document.vm()); 45 auto applePayAMSUIRequest = convertDictionary<ApplePayAMSUIRequest>(*document.globalObject(), data); 46 46 if (throwScope.exception()) 47 47 return Exception { ExistingExceptionError }; … … 119 119 } 120 120 121 ExceptionOr<void> ApplePayAMSUIPaymentHandler::convertData( JSC::JSValue data)121 ExceptionOr<void> ApplePayAMSUIPaymentHandler::convertData(Document& document, JSC::JSValue data) 122 122 { 123 auto requestOrException = convertAndValidateApplePayAMSUIRequest( *scriptExecutionContext(), data);123 auto requestOrException = convertAndValidateApplePayAMSUIRequest(document, data); 124 124 if (requestOrException.hasException()) 125 125 return requestOrException.releaseException(); -
trunk/Source/WebCore/Modules/applepay-ams-ui/ApplePayAMSUIPaymentHandler.h
r285444 r286452 69 69 70 70 // PaymentHandler 71 ExceptionOr<void> convertData( JSC::JSValue) final;71 ExceptionOr<void> convertData(Document&, JSC::JSValue) final; 72 72 ExceptionOr<void> show(Document&) final; 73 73 bool canAbortSession() final { return false; } -
trunk/Source/WebCore/Modules/applepay/ApplePaySession.cpp
r282464 r286452 180 180 181 181 // FIXME: Merge this validation into the validation we are doing above. 182 auto validatedPaymentRequest = PaymentRequestValidator::validate(result); 182 constexpr OptionSet fieldsToValidate = { 183 PaymentRequestValidator::Field::MerchantCapabilities, 184 PaymentRequestValidator::Field::SupportedNetworks, 185 PaymentRequestValidator::Field::CountryCode, 186 PaymentRequestValidator::Field::CurrencyCode, 187 PaymentRequestValidator::Field::Total, 188 PaymentRequestValidator::Field::ShippingMethods, 189 }; 190 auto validatedPaymentRequest = PaymentRequestValidator::validate(result, fieldsToValidate); 183 191 if (validatedPaymentRequest.hasException()) 184 192 return validatedPaymentRequest.releaseException(); -
trunk/Source/WebCore/Modules/applepay/PaymentRequestValidator.h
r273113 r286452 30 30 #include "ApplePaySessionPaymentRequest.h" 31 31 #include "ExceptionOr.h" 32 #include <wtf/OptionSet.h> 32 33 33 34 namespace WebCore { … … 35 36 class PaymentRequestValidator { 36 37 public: 37 static ExceptionOr<void> validate(const ApplePaySessionPaymentRequest&); 38 enum class Field : uint8_t { 39 MerchantCapabilities = 1 << 0, 40 SupportedNetworks = 1 << 1, 41 CountryCode = 1 << 2, 42 CurrencyCode = 1 << 3, 43 Total = 1 << 4, 44 ShippingMethods = 1 << 5, 45 }; 46 47 static ExceptionOr<void> validate(const ApplePaySessionPaymentRequest&, OptionSet<PaymentRequestValidator::Field>); 38 48 static ExceptionOr<void> validateTotal(const ApplePayLineItem&); 39 49 }; -
trunk/Source/WebCore/Modules/applepay/PaymentRequestValidator.mm
r275084 r286452 44 44 static ExceptionOr<void> validateShippingMethod(const ApplePayShippingMethod&); 45 45 46 ExceptionOr<void> PaymentRequestValidator::validate(const ApplePaySessionPaymentRequest& paymentRequest )46 ExceptionOr<void> PaymentRequestValidator::validate(const ApplePaySessionPaymentRequest& paymentRequest, OptionSet<Field> fieldsToValidate) 47 47 { 48 auto validatedCountryCode = validateCountryCode(paymentRequest.countryCode()); 49 if (validatedCountryCode.hasException()) 50 return validatedCountryCode.releaseException(); 51 52 auto validatedCurrencyCode = validateCurrencyCode(paymentRequest.currencyCode()); 53 if (validatedCurrencyCode.hasException()) 54 return validatedCurrencyCode.releaseException(); 55 56 auto validatedSupportedNetworks = validateSupportedNetworks(paymentRequest.supportedNetworks()); 57 if (validatedSupportedNetworks.hasException()) 58 return validatedSupportedNetworks.releaseException(); 59 60 auto validatedMerchantCapabilities = validateMerchantCapabilities(paymentRequest.merchantCapabilities()); 61 if (validatedMerchantCapabilities.hasException()) 62 return validatedMerchantCapabilities.releaseException(); 63 64 auto validatedTotal = validateTotal(paymentRequest.total()); 65 if (validatedTotal.hasException()) 66 return validatedTotal.releaseException(); 67 68 auto validatedShippingMethods = validateShippingMethods(paymentRequest.shippingMethods()); 69 if (validatedShippingMethods.hasException()) 70 return validatedShippingMethods.releaseException(); 71 72 for (auto& countryCode : paymentRequest.supportedCountries()) { 73 auto validatedCountryCode = validateCountryCode(countryCode); 48 if (fieldsToValidate.contains(Field::CountryCode)) { 49 auto validatedCountryCode = validateCountryCode(paymentRequest.countryCode()); 74 50 if (validatedCountryCode.hasException()) 75 51 return validatedCountryCode.releaseException(); 52 } 53 54 if (fieldsToValidate.contains(Field::CurrencyCode)) { 55 auto validatedCurrencyCode = validateCurrencyCode(paymentRequest.currencyCode()); 56 if (validatedCurrencyCode.hasException()) 57 return validatedCurrencyCode.releaseException(); 58 } 59 60 if (fieldsToValidate.contains(Field::SupportedNetworks)) { 61 auto validatedSupportedNetworks = validateSupportedNetworks(paymentRequest.supportedNetworks()); 62 if (validatedSupportedNetworks.hasException()) 63 return validatedSupportedNetworks.releaseException(); 64 } 65 66 if (fieldsToValidate.contains(Field::MerchantCapabilities)) { 67 auto validatedMerchantCapabilities = validateMerchantCapabilities(paymentRequest.merchantCapabilities()); 68 if (validatedMerchantCapabilities.hasException()) 69 return validatedMerchantCapabilities.releaseException(); 70 } 71 72 if (fieldsToValidate.contains(Field::Total)) { 73 auto validatedTotal = validateTotal(paymentRequest.total()); 74 if (validatedTotal.hasException()) 75 return validatedTotal.releaseException(); 76 } 77 78 if (fieldsToValidate.contains(Field::ShippingMethods)) { 79 auto validatedShippingMethods = validateShippingMethods(paymentRequest.shippingMethods()); 80 if (validatedShippingMethods.hasException()) 81 return validatedShippingMethods.releaseException(); 82 } 83 84 if (fieldsToValidate.contains(Field::CountryCode)) { 85 for (auto& countryCode : paymentRequest.supportedCountries()) { 86 auto validatedCountryCode = validateCountryCode(countryCode); 87 if (validatedCountryCode.hasException()) 88 return validatedCountryCode.releaseException(); 89 } 76 90 } 77 91 -
trunk/Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.cpp
r285521 r286452 79 79 namespace WebCore { 80 80 81 static ExceptionOr<ApplePayRequest> convertAndValidateApplePayRequest(ScriptExecutionContext& context, JSC::JSValue data) 81 static inline PaymentCoordinator& paymentCoordinator(Document& document) 82 { 83 ASSERT(document.page()); 84 return document.page()->paymentCoordinator(); 85 } 86 87 static ExceptionOr<ApplePayRequest> convertAndValidateApplePayRequest(Document& document, JSC::JSValue data) 82 88 { 83 89 if (data.isEmpty()) 84 90 return Exception { TypeError, "Missing payment method data." }; 85 91 86 auto throwScope = DECLARE_THROW_SCOPE( context.vm());87 auto applePayRequest = convertDictionary<ApplePayRequest>(* context.globalObject(), data);92 auto throwScope = DECLARE_THROW_SCOPE(document.vm()); 93 auto applePayRequest = convertDictionary<ApplePayRequest>(*document.globalObject(), data); 88 94 if (throwScope.exception()) 89 95 return Exception { ExistingExceptionError }; 96 97 auto validatedRequest = convertAndValidate(document, applePayRequest.version, applePayRequest, paymentCoordinator(document)); 98 if (validatedRequest.hasException()) 99 return validatedRequest.releaseException(); 100 101 constexpr OptionSet fieldsToValidate = { 102 PaymentRequestValidator::Field::MerchantCapabilities, 103 PaymentRequestValidator::Field::SupportedNetworks, 104 PaymentRequestValidator::Field::CountryCode, 105 }; 106 auto exception = PaymentRequestValidator::validate(validatedRequest.releaseReturnValue(), fieldsToValidate); 107 if (exception.hasException()) 108 return exception.releaseException(); 90 109 91 110 return WTFMove(applePayRequest); … … 108 127 auto& url = std::get<URL>(identifier); 109 128 return url.host() == "apple.com" && url.path() == "/apple-pay"; 110 }111 112 static inline PaymentCoordinator& paymentCoordinator(Document& document)113 {114 ASSERT(document.page());115 return document.page()->paymentCoordinator();116 129 } 117 130 … … 201 214 } 202 215 203 ExceptionOr<void> ApplePayPaymentHandler::convertData( JSC::JSValue data)204 { 205 auto requestOrException = convertAndValidateApplePayRequest( *scriptExecutionContext(), data);216 ExceptionOr<void> ApplePayPaymentHandler::convertData(Document& document, JSC::JSValue data) 217 { 218 auto requestOrException = convertAndValidateApplePayRequest(document, data); 206 219 if (requestOrException.hasException()) 207 220 return requestOrException.releaseException(); … … 270 283 merge(request, WTFMove(std::get<1>(*modifierData))); 271 284 272 auto exception = PaymentRequestValidator::validate(request); 285 constexpr OptionSet fieldsToValidate = { 286 PaymentRequestValidator::Field::CurrencyCode, 287 PaymentRequestValidator::Field::Total, 288 PaymentRequestValidator::Field::ShippingMethods, 289 }; 290 auto exception = PaymentRequestValidator::validate(request, fieldsToValidate); 273 291 if (exception.hasException()) 274 292 return exception.releaseException(); -
trunk/Source/WebCore/Modules/applepay/paymentrequest/ApplePayPaymentHandler.h
r285444 r286452 72 72 73 73 // PaymentHandler 74 ExceptionOr<void> convertData( JSC::JSValue) final;74 ExceptionOr<void> convertData(Document&, JSC::JSValue) final; 75 75 ExceptionOr<void> show(Document&) final; 76 76 bool canAbortSession() final { return true; } -
trunk/Source/WebCore/Modules/paymentrequest/PaymentHandler.h
r285444 r286452 51 51 static bool hasActiveSession(Document&); 52 52 53 virtual ExceptionOr<void> convertData( JSC::JSValue) = 0;53 virtual ExceptionOr<void> convertData(Document&, JSC::JSValue) = 0; 54 54 virtual ExceptionOr<void> show(Document&) = 0; 55 55 virtual bool canAbortSession() = 0; -
trunk/Source/WebCore/Modules/paymentrequest/PaymentRequest.cpp
r285521 r286452 411 411 continue; 412 412 413 auto result = handler->convertData(d ata.releaseReturnValue());413 auto result = handler->convertData(document, data.releaseReturnValue()); 414 414 if (result.hasException()) { 415 415 settleShowPromise(result.releaseException());
Note: See TracChangeset
for help on using the changeset viewer.