1 // Copyright 2017 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 
5 #include "components/autofill/core/browser/autofill_handler.h"
6 
7 #include "base/containers/adapters.h"
8 #include "components/autofill/core/browser/form_structure.h"
9 #include "components/autofill/core/browser/logging/log_manager.h"
10 #include "components/autofill/core/common/autofill_data_validation.h"
11 #include "components/autofill/core/common/autofill_internals/log_message.h"
12 #include "components/autofill/core/common/autofill_internals/logging_scope.h"
13 #include "components/autofill/core/common/autofill_payments_features.h"
14 #include "components/autofill/core/common/autofill_tick_clock.h"
15 #include "components/autofill/core/common/signatures_util.h"
16 #include "ui/gfx/geometry/rect_f.h"
17 
18 namespace autofill {
19 
20 namespace {
21 
22 // Set a conservative upper bound on the number of forms we are willing to
23 // cache, simply to prevent unbounded memory consumption.
24 const size_t kAutofillHandlerMaxFormCacheSize = 100;
25 
26 // Returns the AutofillField* corresponding to |field| in |form| or nullptr,
27 // if not found.
FindAutofillFillField(const FormStructure & form,const FormFieldData & field)28 AutofillField* FindAutofillFillField(const FormStructure& form,
29                                      const FormFieldData& field) {
30   for (const auto& cur_field : form) {
31     if (cur_field->SameFieldAs(field)) {
32       return cur_field.get();
33     }
34   }
35   return nullptr;
36 }
37 
38 // Returns true if |live_form| does not match |cached_form|.
CachedFormNeedsUpdate(const FormData & live_form,const FormStructure & cached_form)39 bool CachedFormNeedsUpdate(const FormData& live_form,
40                            const FormStructure& cached_form) {
41   if (live_form.fields.size() != cached_form.field_count())
42     return true;
43 
44   for (size_t i = 0; i < cached_form.field_count(); ++i) {
45     if (!cached_form.field(i)->SameFieldAs(live_form.fields[i]))
46       return true;
47   }
48 
49   return false;
50 }
51 
52 }  // namespace
53 
54 using base::TimeTicks;
55 
AutofillHandler(AutofillDriver * driver,LogManager * log_manager)56 AutofillHandler::AutofillHandler(AutofillDriver* driver,
57                                  LogManager* log_manager)
58     : driver_(driver), log_manager_(log_manager) {}
59 
60 AutofillHandler::~AutofillHandler() = default;
61 
OnFormSubmitted(const FormData & form,bool known_success,mojom::SubmissionSource source)62 void AutofillHandler::OnFormSubmitted(const FormData& form,
63                                       bool known_success,
64                                       mojom::SubmissionSource source) {
65   if (IsValidFormData(form))
66     OnFormSubmittedImpl(form, known_success, source);
67 }
68 
OnFormsSeen(const std::vector<FormData> & forms,const base::TimeTicks timestamp)69 void AutofillHandler::OnFormsSeen(const std::vector<FormData>& forms,
70                                   const base::TimeTicks timestamp) {
71   if (!IsValidFormDataVector(forms) || !driver_->RendererIsAvailable())
72     return;
73 
74   // This should be called even forms is empty, AutofillProviderAndroid uses
75   // this event to detect form submission.
76   if (!ShouldParseForms(forms, timestamp))
77     return;
78 
79   if (forms.empty())
80     return;
81 
82   // Parse each of the forms. Because parsing a given FormData may invalidate
83   // and replace a form parsed before it (invalidating any pointers we might
84   // hold) we track the newly created form signatures instead of remembering
85   // the pointer values.
86   std::set<FormSignature> new_form_signatures;
87   for (const FormData& form : forms) {
88     const auto parse_form_start_time = AutofillTickClock::NowTicks();
89     FormStructure* cached_form_structure = nullptr;
90     FormStructure* form_structure = nullptr;
91     // Try to find the FormStructure that corresponds to |form| if the form
92     // contains credit card fields only.
93     // |cached_form_structure| may still be nullptr after this call.
94     ignore_result(FindCachedForm(form, &cached_form_structure));
95     if (cached_form_structure) {
96       for (const FormType& form_type : cached_form_structure->GetFormTypes()) {
97         if (form_type != CREDIT_CARD_FORM) {
98           cached_form_structure = nullptr;
99           break;
100         }
101       }
102     }
103 
104     if (!ParseForm(form, cached_form_structure, &form_structure))
105       continue;
106     DCHECK(form_structure);
107     new_form_signatures.insert(form_structure->form_signature());
108     AutofillMetrics::LogParseFormTiming(AutofillTickClock::NowTicks() -
109                                         parse_form_start_time);
110   }
111 
112   if (new_form_signatures.empty())
113     return;
114 
115   // Populate the set of newly created form structures and call the
116   // OnFormsParsed handler.
117   std::vector<FormStructure*> new_form_structures;
118   new_form_structures.reserve(new_form_signatures.size());
119   for (auto signature : new_form_signatures) {
120     FormStructure* form_structure = nullptr;
121     if (FindCachedForm(signature, &form_structure) && form_structure) {
122       new_form_structures.push_back(form_structure);
123     } else {
124       NOTREACHED();
125     }
126   }
127   OnFormsParsed(new_form_structures, timestamp);
128 }
129 
OnTextFieldDidChange(const FormData & form,const FormFieldData & field,const gfx::RectF & bounding_box,const TimeTicks timestamp)130 void AutofillHandler::OnTextFieldDidChange(const FormData& form,
131                                            const FormFieldData& field,
132                                            const gfx::RectF& bounding_box,
133                                            const TimeTicks timestamp) {
134   if (!IsValidFormData(form) || !IsValidFormFieldData(field))
135     return;
136 
137   gfx::RectF transformed_box =
138       driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
139 
140   OnTextFieldDidChangeImpl(form, field, transformed_box, timestamp);
141 }
142 
OnTextFieldDidScroll(const FormData & form,const FormFieldData & field,const gfx::RectF & bounding_box)143 void AutofillHandler::OnTextFieldDidScroll(const FormData& form,
144                                            const FormFieldData& field,
145                                            const gfx::RectF& bounding_box) {
146   if (!IsValidFormData(form) || !IsValidFormFieldData(field))
147     return;
148 
149   gfx::RectF transformed_box =
150       driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
151 
152   OnTextFieldDidScrollImpl(form, field, transformed_box);
153 }
154 
OnSelectControlDidChange(const FormData & form,const FormFieldData & field,const gfx::RectF & bounding_box)155 void AutofillHandler::OnSelectControlDidChange(const FormData& form,
156                                                const FormFieldData& field,
157                                                const gfx::RectF& bounding_box) {
158   if (!IsValidFormData(form) || !IsValidFormFieldData(field))
159     return;
160 
161   gfx::RectF transformed_box =
162       driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
163 
164   OnSelectControlDidChangeImpl(form, field, transformed_box);
165 }
166 
OnQueryFormFieldAutofill(int query_id,const FormData & form,const FormFieldData & field,const gfx::RectF & bounding_box,bool autoselect_first_suggestion)167 void AutofillHandler::OnQueryFormFieldAutofill(
168     int query_id,
169     const FormData& form,
170     const FormFieldData& field,
171     const gfx::RectF& bounding_box,
172     bool autoselect_first_suggestion) {
173   if (!IsValidFormData(form) || !IsValidFormFieldData(field))
174     return;
175 
176   gfx::RectF transformed_box =
177       driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
178 
179   OnQueryFormFieldAutofillImpl(query_id, form, field, transformed_box,
180                                autoselect_first_suggestion);
181 }
182 
OnFocusOnFormField(const FormData & form,const FormFieldData & field,const gfx::RectF & bounding_box)183 void AutofillHandler::OnFocusOnFormField(const FormData& form,
184                                          const FormFieldData& field,
185                                          const gfx::RectF& bounding_box) {
186   if (!IsValidFormData(form) || !IsValidFormFieldData(field))
187     return;
188 
189   gfx::RectF transformed_box =
190       driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
191 
192   OnFocusOnFormFieldImpl(form, field, transformed_box);
193 }
194 
SendFormDataToRenderer(int query_id,AutofillDriver::RendererFormDataAction action,const FormData & data)195 void AutofillHandler::SendFormDataToRenderer(
196     int query_id,
197     AutofillDriver::RendererFormDataAction action,
198     const FormData& data) {
199   driver_->SendFormDataToRenderer(query_id, action, data);
200 }
201 
GetCachedFormAndField(const FormData & form,const FormFieldData & field,FormStructure ** form_structure,AutofillField ** autofill_field)202 bool AutofillHandler::GetCachedFormAndField(const FormData& form,
203                                             const FormFieldData& field,
204                                             FormStructure** form_structure,
205                                             AutofillField** autofill_field) {
206   // Maybe find an existing FormStructure that corresponds to |form|.
207   FormStructure* cached_form = nullptr;
208   if (FindCachedForm(form, &cached_form)) {
209     DCHECK(cached_form);
210     if (!CachedFormNeedsUpdate(form, *cached_form)) {
211       // There is no data to return if there are no auto-fillable fields.
212       if (!cached_form->autofill_count())
213         return false;
214 
215       // Return the cached form and matching field, if any.
216       *form_structure = cached_form;
217       *autofill_field = FindAutofillFillField(**form_structure, field);
218       return *autofill_field != nullptr;
219     }
220   }
221 
222   // The form is new or updated, parse it and discard |cached_form|.
223   // i.e., |cached_form| is no longer valid after this call.
224   if (!ParseForm(form, std::move(cached_form), form_structure))
225     return false;
226 
227   // Annotate the updated form with its predicted types.
228   driver()->SendAutofillTypePredictionsToRenderer({*form_structure});
229 
230   // There is no data to return if there are no auto-fillable fields.
231   if (!(*form_structure)->autofill_count())
232     return false;
233 
234   // Find the AutofillField that corresponds to |field|.
235   *autofill_field = FindAutofillFillField(**form_structure, field);
236   return *autofill_field != nullptr;
237 }
238 
FindCachedForm(FormSignature form_signature,FormStructure ** form_structure) const239 bool AutofillHandler::FindCachedForm(FormSignature form_signature,
240                                      FormStructure** form_structure) const {
241   auto it = form_structures_.find(form_signature);
242   if (it != form_structures_.end()) {
243     *form_structure = it->second.get();
244     return true;
245   }
246   return false;
247 }
248 
FindCachedForm(const FormData & form,FormStructure ** form_structure) const249 bool AutofillHandler::FindCachedForm(const FormData& form,
250                                      FormStructure** form_structure) const {
251   // Find the FormStructure that corresponds to |form|.
252   if (FindCachedForm(autofill::CalculateFormSignature(form), form_structure))
253     return true;
254 
255   // The form might have been modified by JavaScript which resulted in a change
256   // of form signature. Compare it to all the forms in the cache to look for a
257   // match.
258   for (const auto& it : form_structures_) {
259     if (*it.second == form) {
260       *form_structure = it.second.get();
261       return true;
262     }
263   }
264 
265   *form_structure = nullptr;
266   return false;
267 }
268 
ParseForm(const FormData & form,const FormStructure * cached_form,FormStructure ** parsed_form_structure)269 bool AutofillHandler::ParseForm(const FormData& form,
270                                 const FormStructure* cached_form,
271                                 FormStructure** parsed_form_structure) {
272   DCHECK(parsed_form_structure);
273   if (form_structures_.size() >= kAutofillHandlerMaxFormCacheSize) {
274     if (log_manager_) {
275       log_manager_->Log() << LoggingScope::kAbortParsing
276                           << LogMessage::kAbortParsingTooManyForms << form;
277     }
278     return false;
279   }
280 
281   auto form_structure = std::make_unique<FormStructure>(form);
282   form_structure->ParseFieldTypesFromAutocompleteAttributes();
283   if (!form_structure->ShouldBeParsed(log_manager_))
284     return false;
285 
286   if (cached_form) {
287     // We need to keep the server data if available. We need to use them while
288     // determining the heuristics.
289     form_structure->RetrieveFromCache(*cached_form,
290                                       /*should_keep_cached_value=*/true,
291                                       /*only_server_and_autofill_state=*/true);
292     if (observer_for_testing_)
293       observer_for_testing_->OnFormParsed();
294 
295     if (form_structure.get()->value_from_dynamic_change_form())
296       value_from_dynamic_change_form_ = true;
297   }
298 
299   form_structure->DetermineHeuristicTypes(log_manager_);
300 
301   // Hold the parsed_form_structure we intend to return. We can use this to
302   // reference the form_signature when transferring ownership below.
303   *parsed_form_structure = form_structure.get();
304 
305   // Ownership is transferred to |form_structures_| which maintains it until
306   // the form is parsed again or the AutofillHandler is destroyed.
307   //
308   // Note that this insert/update takes ownership of the new form structure
309   // and also destroys the previously cached form structure.
310   form_structures_[(*parsed_form_structure)->form_signature()] =
311       std::move(form_structure);
312 
313   return true;
314 }
315 
Reset()316 void AutofillHandler::Reset() {
317   form_structures_.clear();
318 }
319 
320 }  // namespace autofill
321