diff options
Diffstat (limited to 'chromium/components/autofill/core')
-rw-r--r-- | chromium/components/autofill/core/browser/browser_autofill_manager.cc | 38 | ||||
-rw-r--r-- | chromium/components/autofill/core/browser/browser_autofill_manager.h | 8 |
2 files changed, 28 insertions, 18 deletions
diff --git a/chromium/components/autofill/core/browser/browser_autofill_manager.cc b/chromium/components/autofill/core/browser/browser_autofill_manager.cc index 6a584ff0a0a..35385875593 100644 --- a/chromium/components/autofill/core/browser/browser_autofill_manager.cc +++ b/chromium/components/autofill/core/browser/browser_autofill_manager.cc @@ -1157,26 +1157,36 @@ void BrowserAutofillManager::OnAskForValuesToFillImpl( #if !defined(TOOLKIT_QT) bool BrowserAutofillManager::WillFillCreditCardNumber( const FormData& form, - const FormFieldData& field) { + const FormFieldData& triggered_field_data) { FormStructure* form_structure = nullptr; - AutofillField* autofill_field = nullptr; - if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field)) + AutofillField* triggered_field = nullptr; + if (!GetCachedFormAndField(form, triggered_field_data, &form_structure, + &triggered_field)) { return false; + } - if (autofill_field->Type().GetStorableType() == CREDIT_CARD_NUMBER) + if (triggered_field->Type().GetStorableType() == CREDIT_CARD_NUMBER) return true; - DCHECK_EQ(form_structure->field_count(), form.fields.size()); - for (size_t i = 0; i < form_structure->field_count(); ++i) { - if (form_structure->field(i)->section == autofill_field->section && - form_structure->field(i)->Type().GetStorableType() == - CREDIT_CARD_NUMBER && - form.fields[i].value.empty() && !form.fields[i].is_autofilled) { - return true; - } - } + // `form` is the latest version of the form received from the renderer and may + // be more up to date than the `form_structure` in the cache. Therefore, we + // need to validate for each `field` in the cache we try to fill whether + // it still exists in the renderer and whether it is fillable. + auto IsFillableField = [&form](FieldGlobalId id) { + auto it = base::ranges::find(form.fields, id, &FormFieldData::global_id); + return it != form.fields.end() && it->value.empty() && !it->is_autofilled; + }; - return false; + auto IsFillableCreditCardNumberField = [&triggered_field, + &IsFillableField](const auto& field) { + return field->Type().GetStorableType() == CREDIT_CARD_NUMBER && + field->section == triggered_field->section && + IsFillableField(field->global_id()); + }; + + // This runs O(N^2) in the worst case, but usually there aren't too many + // credit card number fields in a form. + return base::ranges::any_of(*form_structure, IsFillableCreditCardNumberField); } void BrowserAutofillManager::FillOrPreviewCreditCardForm( diff --git a/chromium/components/autofill/core/browser/browser_autofill_manager.h b/chromium/components/autofill/core/browser/browser_autofill_manager.h index 883fa92634a..0d968e1ff56 100644 --- a/chromium/components/autofill/core/browser/browser_autofill_manager.h +++ b/chromium/components/autofill/core/browser/browser_autofill_manager.h @@ -520,11 +520,11 @@ class BrowserAutofillManager : public AutofillManager, // profile does not exist. AutofillProfile* GetProfile(int unique_id); - // Determines whether a fill on |form| initiated from |field| will wind up - // filling a credit card number. This is useful to determine if we will need - // to unmask a card. + // Determines whether a fill on |form| initiated from |triggered_field| will + // wind up filling a credit card number. This is useful to determine if we + // will need to unmask a card. bool WillFillCreditCardNumber(const FormData& form, - const FormFieldData& field); + const FormFieldData& triggered_field); // Fills or previews the credit card form. // Assumes the form and field are valid. |