Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1444)

Side by Side Diff: third_party/WebKit/Source/modules/payments/PaymentRequest.cpp

Issue 2500183002: Do not parse JSON in the browser. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/modules/payments/PaymentRequest.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/payments/PaymentRequest.h" 5 #include "modules/payments/PaymentRequest.h"
6 6
7 #include "bindings/core/v8/ExceptionState.h" 7 #include "bindings/core/v8/ExceptionState.h"
8 #include "bindings/core/v8/ScriptPromiseResolver.h" 8 #include "bindings/core/v8/ScriptPromiseResolver.h"
9 #include "bindings/core/v8/ScriptState.h" 9 #include "bindings/core/v8/ScriptState.h"
10 #include "bindings/core/v8/V8StringResource.h" 10 #include "bindings/core/v8/V8StringResource.h"
11 #include "bindings/modules/v8/V8AndroidPayMethodData.h"
11 #include "bindings/modules/v8/V8PaymentDetails.h" 12 #include "bindings/modules/v8/V8PaymentDetails.h"
12 #include "core/EventTypeNames.h" 13 #include "core/EventTypeNames.h"
13 #include "core/dom/DOMException.h" 14 #include "core/dom/DOMException.h"
14 #include "core/dom/ExceptionCode.h" 15 #include "core/dom/ExceptionCode.h"
15 #include "core/events/Event.h" 16 #include "core/events/Event.h"
16 #include "core/events/EventQueue.h" 17 #include "core/events/EventQueue.h"
17 #include "core/frame/FrameOwner.h" 18 #include "core/frame/FrameOwner.h"
18 #include "core/html/HTMLIFrameElement.h" 19 #include "core/html/HTMLIFrameElement.h"
19 #include "modules/EventTargetModulesNames.h" 20 #include "modules/EventTargetModulesNames.h"
21 #include "modules/payments/AndroidPayMethodData.h"
22 #include "modules/payments/AndroidPayTokenization.h"
20 #include "modules/payments/HTMLIFrameElementPayments.h" 23 #include "modules/payments/HTMLIFrameElementPayments.h"
21 #include "modules/payments/PaymentAddress.h" 24 #include "modules/payments/PaymentAddress.h"
22 #include "modules/payments/PaymentItem.h" 25 #include "modules/payments/PaymentItem.h"
23 #include "modules/payments/PaymentRequestUpdateEvent.h" 26 #include "modules/payments/PaymentRequestUpdateEvent.h"
24 #include "modules/payments/PaymentResponse.h" 27 #include "modules/payments/PaymentResponse.h"
25 #include "modules/payments/PaymentShippingOption.h" 28 #include "modules/payments/PaymentShippingOption.h"
26 #include "modules/payments/PaymentsValidators.h" 29 #include "modules/payments/PaymentsValidators.h"
27 #include "mojo/public/cpp/bindings/interface_request.h" 30 #include "mojo/public/cpp/bindings/interface_request.h"
28 #include "mojo/public/cpp/bindings/wtf_array.h" 31 #include "mojo/public/cpp/bindings/wtf_array.h"
29 #include "platform/mojo/MojoHelper.h" 32 #include "platform/mojo/MojoHelper.h"
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 output->shipping_type = PaymentShippingType::DELIVERY; 162 output->shipping_type = PaymentShippingType::DELIVERY;
160 else if (input.shippingType() == "pickup") 163 else if (input.shippingType() == "pickup")
161 output->shipping_type = PaymentShippingType::PICKUP; 164 output->shipping_type = PaymentShippingType::PICKUP;
162 else 165 else
163 output->shipping_type = PaymentShippingType::SHIPPING; 166 output->shipping_type = PaymentShippingType::SHIPPING;
164 167
165 return output; 168 return output;
166 } 169 }
167 }; 170 };
168 171
169 template <>
170 struct TypeConverter<WTFArray<PaymentMethodDataPtr>,
171 WTF::Vector<blink::PaymentRequest::MethodData>> {
172 static WTFArray<PaymentMethodDataPtr> Convert(
173 const WTF::Vector<blink::PaymentRequest::MethodData>& input) {
174 WTFArray<PaymentMethodDataPtr> output(input.size());
175 for (size_t i = 0; i < input.size(); ++i) {
176 output[i] = PaymentMethodData::New();
177 output[i]->supported_methods =
178 WTF::Vector<WTF::String>(input[i].supportedMethods);
179 output[i]->stringified_data = input[i].stringifiedData;
180 }
181 return output;
182 }
183 };
184
185 } // namespace mojo 172 } // namespace mojo
186 173
187 namespace blink { 174 namespace blink {
188 namespace { 175 namespace {
189 176
190 // If the website does not call complete() 60 seconds after show() has been 177 // If the website does not call complete() 60 seconds after show() has been
191 // resolved, then behave as if the website called complete("fail"). 178 // resolved, then behave as if the website called complete("fail").
192 static const int completeTimeoutSeconds = 60; 179 static const int completeTimeoutSeconds = 60;
193 180
194 // Validates ShippingOption or PaymentItem, which happen to have identical 181 // Validates ShippingOption or PaymentItem, which happen to have identical
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 329
343 String errorMessage; 330 String errorMessage;
344 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(), 331 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(),
345 &errorMessage)) { 332 &errorMessage)) {
346 exceptionState.throwTypeError(errorMessage); 333 exceptionState.throwTypeError(errorMessage);
347 } 334 }
348 335
349 return keepShippingOptions; 336 return keepShippingOptions;
350 } 337 }
351 338
339 void maybeSetAndroidPayMethodata(
340 const ScriptValue& input,
341 payments::mojom::blink::PaymentMethodDataPtr& output) {
342 AndroidPayMethodData androidPay;
343 TrackExceptionState exceptionState;
344 V8AndroidPayMethodData::toImpl(input.isolate(), input.v8Value(), androidPay,
345 exceptionState);
346 if (exceptionState.hadException())
347 return;
348
349 if (androidPay.hasEnvironment() && androidPay.environment() == "TEST")
350 output->environment = payments::mojom::blink::AndroidPayEnvironment::TEST;
351
352 output->merchant_name = androidPay.merchantName();
353 output->merchant_id = androidPay.merchantId();
354
355 if (androidPay.hasAllowedCardNetworks()) {
356 output->allowed_card_networks.resize(
357 androidPay.allowedCardNetworks().size());
358 for (size_t i = 0; i < androidPay.allowedCardNetworks().size(); ++i) {
359 const String& network = androidPay.allowedCardNetworks()[i];
360 if (network == "AMEX") {
361 output->allowed_card_networks[i] =
362 payments::mojom::blink::AndroidPayCardNetwork::AMEX;
363 } else if (network == "DISCOVER") {
364 output->allowed_card_networks[i] =
365 payments::mojom::blink::AndroidPayCardNetwork::DISCOVER;
366 } else if (network == "MASTERCARD") {
367 output->allowed_card_networks[i] =
368 payments::mojom::blink::AndroidPayCardNetwork::MASTERCARD;
369 } else if (network == "VISA") {
370 output->allowed_card_networks[i] =
371 payments::mojom::blink::AndroidPayCardNetwork::VISA;
372 } else {
373 output->allowed_card_networks[i] =
374 payments::mojom::blink::AndroidPayCardNetwork::UNKNOWN;
375 }
376 }
377 }
378
379 if (androidPay.hasPaymentMethodTokenizationParameters()) {
380 const AndroidPayTokenization& tokenization =
381 androidPay.paymentMethodTokenizationParameters();
382 if (tokenization.hasTokenizationType()) {
383 if (tokenization.tokenizationType() == "GATEWAY_TOKEN") {
384 output->tokenization_type =
385 payments::mojom::blink::AndroidPayTokenization::GATEWAY_TOKEN;
386 } else if (tokenization.tokenizationType() == "NETWORK_TOKEN") {
387 output->tokenization_type =
388 payments::mojom::blink::AndroidPayTokenization::NETWORK_TOKEN;
389 } else {
390 output->tokenization_type =
391 payments::mojom::blink::AndroidPayTokenization::UNSPECIFIED;
392 }
393 }
394
395 if (tokenization.hasParameters() &&
396 tokenization.parameters().v8Value()->IsObject() &&
397 !tokenization.parameters().v8Value()->IsArray()) {
398 const ScriptValue& parameters = tokenization.parameters();
Marijn Kruisselbrink 2016/11/16 19:09:13 I mentioned that record<DOMString, DOMString> or s
please use gerrit instead 2016/11/16 20:23:23 Thank you. Dictionary was exactly what I needed.
399 v8::Local<v8::Array> keys(
400 parameters.v8Value().As<v8::Object>()->GetOwnPropertyNames());
401 output->parameters.resize(keys->Length());
402 for (uint32_t i = 0; i < keys->Length(); ++i) {
403 v8::Local<v8::Value> key(keys->Get(i));
404 if (key->IsString()) {
405 v8::TryCatch tryCatch(parameters.isolate());
406 v8::Local<v8::Value> value =
407 parameters.v8Value().As<v8::Object>()->Get(key);
408 if (!tryCatch.HasCaught() && value->IsString()) {
409 output->parameters[i] =
410 payments::mojom::blink::AndroidPayTokenizationParameter::New();
411
412 v8::String::Utf8Value utf8Key(key);
413 output->parameters[i]->key = String(*utf8Key, utf8Key.length());
414
415 v8::String::Utf8Value utf8Value(value);
416 output->parameters[i]->value =
417 String(*utf8Value, utf8Value.length());
418 }
419 }
420 }
421 }
422 }
423 }
424
352 void validateAndConvertPaymentMethodData( 425 void validateAndConvertPaymentMethodData(
353 const HeapVector<PaymentMethodData>& paymentMethodDataVector, 426 const HeapVector<PaymentMethodData>& input,
354 Vector<PaymentRequest::MethodData>* methodData, 427 Vector<payments::mojom::blink::PaymentMethodDataPtr>& output,
355 ExceptionState& exceptionState) { 428 ExceptionState& exceptionState) {
356 if (paymentMethodDataVector.isEmpty()) { 429 if (input.isEmpty()) {
357 exceptionState.throwTypeError( 430 exceptionState.throwTypeError(
358 "Must specify at least one payment method identifier"); 431 "Must specify at least one payment method identifier");
359 return; 432 return;
360 } 433 }
361 434
362 for (const auto& paymentMethodData : paymentMethodDataVector) { 435 output.resize(input.size());
436 for (size_t i = 0; i < input.size(); ++i) {
437 const auto& paymentMethodData = input[i];
363 if (paymentMethodData.supportedMethods().isEmpty()) { 438 if (paymentMethodData.supportedMethods().isEmpty()) {
364 exceptionState.throwTypeError( 439 exceptionState.throwTypeError(
365 "Must specify at least one payment method identifier"); 440 "Must specify at least one payment method identifier");
366 return; 441 return;
367 } 442 }
368 443
369 String stringifiedData = ""; 444 String stringifiedData = "";
370 if (paymentMethodData.hasData() && !paymentMethodData.data().isEmpty()) { 445 if (paymentMethodData.hasData() && !paymentMethodData.data().isEmpty()) {
371 if (!paymentMethodData.data().v8Value()->IsObject() || 446 if (!paymentMethodData.data().v8Value()->IsObject() ||
372 paymentMethodData.data().v8Value()->IsArray()) { 447 paymentMethodData.data().v8Value()->IsArray()) {
373 exceptionState.throwTypeError( 448 exceptionState.throwTypeError(
374 "Data should be a JSON-serializable object"); 449 "Data should be a JSON-serializable object");
375 return; 450 return;
376 } 451 }
377 452
378 v8::Local<v8::String> value; 453 v8::Local<v8::String> value;
379 if (!v8::JSON::Stringify( 454 if (!v8::JSON::Stringify(
380 paymentMethodData.data().context(), 455 paymentMethodData.data().context(),
381 paymentMethodData.data().v8Value().As<v8::Object>()) 456 paymentMethodData.data().v8Value().As<v8::Object>())
382 .ToLocal(&value)) { 457 .ToLocal(&value)) {
383 exceptionState.throwTypeError( 458 exceptionState.throwTypeError(
384 "Unable to parse payment method specific data"); 459 "Unable to parse payment method specific data");
385 return; 460 return;
386 } 461 }
387 stringifiedData = 462 stringifiedData =
388 v8StringToWebCoreString<String>(value, DoNotExternalize); 463 v8StringToWebCoreString<String>(value, DoNotExternalize);
389 } 464 }
390 methodData->append(PaymentRequest::MethodData( 465
391 paymentMethodData.supportedMethods(), stringifiedData)); 466 output[i] = payments::mojom::blink::PaymentMethodData::New();
467 output[i]->supported_methods = paymentMethodData.supportedMethods();
468 output[i]->stringified_data = stringifiedData;
469 maybeSetAndroidPayMethodata(paymentMethodData.data(), output[i]);
392 } 470 }
393 } 471 }
394 472
395 String getSelectedShippingOption(const PaymentDetails& details) { 473 String getSelectedShippingOption(const PaymentDetails& details) {
396 String result; 474 String result;
397 if (!details.hasShippingOptions()) 475 if (!details.hasShippingOptions())
398 return result; 476 return result;
399 477
400 for (int i = details.shippingOptions().size() - 1; i >= 0; --i) { 478 for (int i = details.shippingOptions().size() - 1; i >= 0; --i) {
401 if (details.shippingOptions()[i].hasSelected() && 479 if (details.shippingOptions()[i].hasSelected() &&
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 if (ownerElement && isHTMLIFrameElement(ownerElement)) { 526 if (ownerElement && isHTMLIFrameElement(ownerElement)) {
449 HTMLIFrameElement* iframe = toHTMLIFrameElement(ownerElement); 527 HTMLIFrameElement* iframe = toHTMLIFrameElement(ownerElement);
450 if (HTMLIFrameElementPayments::from(*iframe).allowPaymentRequest(*iframe)) 528 if (HTMLIFrameElementPayments::from(*iframe).allowPaymentRequest(*iframe))
451 return allowedToUsePaymentRequest(frame->tree().parent()); 529 return allowedToUsePaymentRequest(frame->tree().parent());
452 } 530 }
453 531
454 // 4. Return false. 532 // 4. Return false.
455 return false; 533 return false;
456 } 534 }
457 535
458 WTF::Vector<payments::mojom::blink::PaymentMethodDataPtr>
459 ConvertPaymentMethodData(
460 const Vector<PaymentRequest::MethodData>& blinkMethods) {
461 WTF::Vector<payments::mojom::blink::PaymentMethodDataPtr> mojoMethods(
462 blinkMethods.size());
463 for (size_t i = 0; i < blinkMethods.size(); ++i) {
464 mojoMethods[i] = payments::mojom::blink::PaymentMethodData::New();
465 mojoMethods[i]->supported_methods =
466 WTF::Vector<WTF::String>(blinkMethods[i].supportedMethods);
467 mojoMethods[i]->stringified_data = blinkMethods[i].stringifiedData;
468 }
469 return mojoMethods;
470 }
471
472 } // namespace 536 } // namespace
473 537
474 PaymentRequest* PaymentRequest::create( 538 PaymentRequest* PaymentRequest::create(
475 ScriptState* scriptState, 539 ScriptState* scriptState,
476 const HeapVector<PaymentMethodData>& methodData, 540 const HeapVector<PaymentMethodData>& methodData,
477 const PaymentDetails& details, 541 const PaymentDetails& details,
478 ExceptionState& exceptionState) { 542 ExceptionState& exceptionState) {
479 return new PaymentRequest(scriptState, methodData, details, PaymentOptions(), 543 return new PaymentRequest(scriptState, methodData, details, PaymentOptions(),
480 exceptionState); 544 exceptionState);
481 } 545 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 PaymentRequest::PaymentRequest(ScriptState* scriptState, 696 PaymentRequest::PaymentRequest(ScriptState* scriptState,
633 const HeapVector<PaymentMethodData>& methodData, 697 const HeapVector<PaymentMethodData>& methodData,
634 const PaymentDetails& details, 698 const PaymentDetails& details,
635 const PaymentOptions& options, 699 const PaymentOptions& options,
636 ExceptionState& exceptionState) 700 ExceptionState& exceptionState)
637 : ContextLifecycleObserver(scriptState->getExecutionContext()), 701 : ContextLifecycleObserver(scriptState->getExecutionContext()),
638 ActiveScriptWrappable(this), 702 ActiveScriptWrappable(this),
639 m_options(options), 703 m_options(options),
640 m_clientBinding(this), 704 m_clientBinding(this),
641 m_completeTimer(this, &PaymentRequest::onCompleteTimeout) { 705 m_completeTimer(this, &PaymentRequest::onCompleteTimeout) {
642 Vector<MethodData> validatedMethodData; 706 Vector<payments::mojom::blink::PaymentMethodDataPtr> validatedMethodData;
643 validateAndConvertPaymentMethodData(methodData, &validatedMethodData, 707 validateAndConvertPaymentMethodData(methodData, validatedMethodData,
644 exceptionState); 708 exceptionState);
645 if (exceptionState.hadException()) 709 if (exceptionState.hadException())
646 return; 710 return;
647 711
648 if (!scriptState->getExecutionContext()->isSecureContext()) { 712 if (!scriptState->getExecutionContext()->isSecureContext()) {
649 exceptionState.throwSecurityError("Must be in a secure context"); 713 exceptionState.throwSecurityError("Must be in a secure context");
650 return; 714 return;
651 } 715 }
652 716
653 if (!allowedToUsePaymentRequest(scriptState->domWindow()->frame())) { 717 if (!allowedToUsePaymentRequest(scriptState->domWindow()->frame())) {
(...skipping 18 matching lines...) Expand all
672 m_shippingType = getValidShippingType(m_options.shippingType()); 736 m_shippingType = getValidShippingType(m_options.shippingType());
673 } 737 }
674 738
675 scriptState->domWindow()->frame()->interfaceProvider()->getInterface( 739 scriptState->domWindow()->frame()->interfaceProvider()->getInterface(
676 mojo::GetProxy(&m_paymentProvider)); 740 mojo::GetProxy(&m_paymentProvider));
677 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( 741 m_paymentProvider.set_connection_error_handler(convertToBaseCallback(
678 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), 742 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this),
679 payments::mojom::blink::PaymentErrorReason::UNKNOWN))); 743 payments::mojom::blink::PaymentErrorReason::UNKNOWN)));
680 m_paymentProvider->Init( 744 m_paymentProvider->Init(
681 m_clientBinding.CreateInterfacePtrAndBind(), 745 m_clientBinding.CreateInterfacePtrAndBind(),
682 ConvertPaymentMethodData(validatedMethodData), 746 std::move(validatedMethodData),
683 maybeKeepShippingOptions( 747 maybeKeepShippingOptions(
684 payments::mojom::blink::PaymentDetails::From(details), 748 payments::mojom::blink::PaymentDetails::From(details),
685 keepShippingOptions && m_options.requestShipping()), 749 keepShippingOptions && m_options.requestShipping()),
686 payments::mojom::blink::PaymentOptions::From(m_options)); 750 payments::mojom::blink::PaymentOptions::From(m_options));
687 } 751 }
688 752
689 void PaymentRequest::contextDestroyed() { 753 void PaymentRequest::contextDestroyed() {
690 clearResolversAndCloseMojoConnection(); 754 clearResolversAndCloseMojoConnection();
691 } 755 }
692 756
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 m_completeTimer.stop(); 922 m_completeTimer.stop();
859 m_completeResolver.clear(); 923 m_completeResolver.clear();
860 m_showResolver.clear(); 924 m_showResolver.clear();
861 m_abortResolver.clear(); 925 m_abortResolver.clear();
862 if (m_clientBinding.is_bound()) 926 if (m_clientBinding.is_bound())
863 m_clientBinding.Close(); 927 m_clientBinding.Close();
864 m_paymentProvider.reset(); 928 m_paymentProvider.reset();
865 } 929 }
866 930
867 } // namespace blink 931 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/payments/PaymentRequest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698