PageRenderTime 23ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/blink/renderer/modules/payments/payments_validators.cc

https://github.com/chromium/chromium
C++ | 199 lines | 157 code | 28 blank | 14 comment | 18 complexity | 89b78beb92ba67fb31fd2c180e89b140 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause
  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
  3. // found in the LICENSE file.
  4. #include "third_party/blink/renderer/modules/payments/payments_validators.h"
  5. #include "services/network/public/cpp/is_potentially_trustworthy.h"
  6. #include "third_party/blink/renderer/bindings/core/v8/script_regexp.h"
  7. #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
  8. #include "third_party/blink/renderer/bindings/modules/v8/v8_address_errors.h"
  9. #include "third_party/blink/renderer/bindings/modules/v8/v8_payer_errors.h"
  10. #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_validation_errors.h"
  11. #include "third_party/blink/renderer/platform/bindings/exception_state.h"
  12. #include "third_party/blink/renderer/platform/bindings/string_resource.h"
  13. #include "third_party/blink/renderer/platform/weborigin/kurl.h"
  14. #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
  15. #include "third_party/blink/renderer/platform/weborigin/security_policy.h"
  16. #include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
  17. #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
  18. namespace blink {
  19. // Passing a giant string through IPC to the browser can cause a crash due to
  20. // failure in memory allocation. This number here is chosen conservatively.
  21. static constexpr size_t kMaximumStringLength = 2 * 1024;
  22. bool PaymentsValidators::IsValidCurrencyCodeFormat(
  23. const String& code,
  24. String* optional_error_message) {
  25. auto* regexp = MakeGarbageCollected<ScriptRegexp>(
  26. "^[A-Z]{3}$", kTextCaseUnicodeInsensitive);
  27. if (regexp->Match(code) == 0)
  28. return true;
  29. if (optional_error_message) {
  30. *optional_error_message = "'" + code +
  31. "' is not a valid ISO 4217 currency code, should "
  32. "be well-formed 3-letter alphabetic code.";
  33. }
  34. return false;
  35. }
  36. bool PaymentsValidators::IsValidAmountFormat(const String& amount,
  37. const String& item_name,
  38. String* optional_error_message) {
  39. auto* regexp = MakeGarbageCollected<ScriptRegexp>("^-?[0-9]+(\\.[0-9]+)?$",
  40. kTextCaseSensitive);
  41. if (regexp->Match(amount) == 0)
  42. return true;
  43. if (optional_error_message) {
  44. *optional_error_message =
  45. "'" + amount + "' is not a valid amount format for " + item_name;
  46. }
  47. return false;
  48. }
  49. bool PaymentsValidators::IsValidCountryCodeFormat(
  50. const String& code,
  51. String* optional_error_message) {
  52. auto* regexp =
  53. MakeGarbageCollected<ScriptRegexp>("^[A-Z]{2}$", kTextCaseSensitive);
  54. if (regexp->Match(code) == 0)
  55. return true;
  56. if (optional_error_message)
  57. *optional_error_message = "'" + code +
  58. "' is not a valid CLDR country code, should be 2 "
  59. "upper case letters [A-Z]";
  60. return false;
  61. }
  62. bool PaymentsValidators::IsValidShippingAddress(
  63. const payments::mojom::blink::PaymentAddressPtr& address,
  64. String* optional_error_message) {
  65. return IsValidCountryCodeFormat(address->country, optional_error_message);
  66. }
  67. bool PaymentsValidators::IsValidErrorMsgFormat(const String& error,
  68. String* optional_error_message) {
  69. if (error.length() <= kMaximumStringLength)
  70. return true;
  71. if (optional_error_message) {
  72. *optional_error_message =
  73. String::Format("Error message should be at most %zu characters long",
  74. kMaximumStringLength);
  75. }
  76. return false;
  77. }
  78. // static
  79. bool PaymentsValidators::IsValidAddressErrorsFormat(
  80. const AddressErrors* errors,
  81. String* optional_error_message) {
  82. return (!errors->hasAddressLine() ||
  83. IsValidErrorMsgFormat(errors->addressLine(),
  84. optional_error_message)) &&
  85. (!errors->hasCity() ||
  86. IsValidErrorMsgFormat(errors->city(), optional_error_message)) &&
  87. (!errors->hasCountry() ||
  88. IsValidErrorMsgFormat(errors->country(), optional_error_message)) &&
  89. (!errors->hasDependentLocality() ||
  90. IsValidErrorMsgFormat(errors->dependentLocality(),
  91. optional_error_message)) &&
  92. (!errors->hasOrganization() ||
  93. IsValidErrorMsgFormat(errors->organization(),
  94. optional_error_message)) &&
  95. (!errors->hasPhone() ||
  96. IsValidErrorMsgFormat(errors->phone(), optional_error_message)) &&
  97. (!errors->hasPostalCode() ||
  98. IsValidErrorMsgFormat(errors->postalCode(),
  99. optional_error_message)) &&
  100. (!errors->hasRecipient() ||
  101. IsValidErrorMsgFormat(errors->recipient(), optional_error_message)) &&
  102. (!errors->hasRegion() ||
  103. IsValidErrorMsgFormat(errors->region(), optional_error_message)) &&
  104. (!errors->hasSortingCode() ||
  105. IsValidErrorMsgFormat(errors->sortingCode(), optional_error_message));
  106. }
  107. // static
  108. bool PaymentsValidators::IsValidPayerErrorsFormat(
  109. const PayerErrors* errors,
  110. String* optional_error_message) {
  111. return (!errors->hasEmail() ||
  112. IsValidErrorMsgFormat(errors->email(), optional_error_message)) &&
  113. (!errors->hasName() ||
  114. IsValidErrorMsgFormat(errors->name(), optional_error_message)) &&
  115. (!errors->hasPhone() ||
  116. IsValidErrorMsgFormat(errors->phone(), optional_error_message));
  117. }
  118. // static
  119. bool PaymentsValidators::IsValidPaymentValidationErrorsFormat(
  120. const PaymentValidationErrors* errors,
  121. String* optional_error_message) {
  122. return (!errors->hasError() ||
  123. IsValidErrorMsgFormat(errors->error(), optional_error_message)) &&
  124. (!errors->hasPayer() ||
  125. IsValidPayerErrorsFormat(errors->payer(), optional_error_message)) &&
  126. (!errors->hasShippingAddress() ||
  127. IsValidAddressErrorsFormat(errors->shippingAddress(),
  128. optional_error_message));
  129. }
  130. bool PaymentsValidators::IsValidMethodFormat(const String& identifier) {
  131. KURL url(NullURL(), identifier);
  132. if (!url.IsValid()) {
  133. // Syntax for a valid standardized PMI:
  134. // https://www.w3.org/TR/payment-method-id/#dfn-syntax-of-a-standardized-payment-method-identifier
  135. auto* regexp = MakeGarbageCollected<ScriptRegexp>(
  136. "^[a-z]+[0-9a-z]*(-[a-z]+[0-9a-z]*)*$", kTextCaseSensitive);
  137. return regexp->Match(identifier) == 0;
  138. }
  139. // URL PMI validation rules:
  140. // https://www.w3.org/TR/payment-method-id/#dfn-validate-a-url-based-payment-method-identifier
  141. if (!url.User().IsEmpty() || !url.Pass().IsEmpty())
  142. return false;
  143. // TODO(http://crbug.com/1200225): Align this with the specification.
  144. return url.ProtocolIsInHTTPFamily() &&
  145. network::IsUrlPotentiallyTrustworthy(GURL(url));
  146. }
  147. void PaymentsValidators::ValidateAndStringifyObject(
  148. v8::Isolate* isolate,
  149. const ScriptValue& input,
  150. String& output,
  151. ExceptionState& exception_state) {
  152. v8::Local<v8::String> value;
  153. if (input.IsEmpty() || !input.V8Value()->IsObject() ||
  154. !v8::JSON::Stringify(isolate->GetCurrentContext(),
  155. input.V8Value().As<v8::Object>())
  156. .ToLocal(&value)) {
  157. exception_state.ThrowTypeError(
  158. "PaymentRequest objects should be JSON-serializable objects");
  159. return;
  160. }
  161. output = ToBlinkString<String>(value, kDoNotExternalize);
  162. // Implementation defined constant controlling the allowed JSON length.
  163. static constexpr size_t kMaxJSONStringLength = 1024 * 1024;
  164. if (output.length() > kMaxJSONStringLength) {
  165. exception_state.ThrowTypeError(
  166. String::Format("JSON serialization of PaymentRequest objects should be "
  167. "no longer than %zu characters",
  168. kMaxJSONStringLength));
  169. }
  170. }
  171. } // namespace blink