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

Side by Side Diff: components/autofill/content/renderer/form_cache.cc

Issue 1161793006: [Autofill] Don't hold onto stale form field pointers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: thestig review Created 5 years, 6 months 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 | « components/autofill/content/renderer/form_cache.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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "components/autofill/content/renderer/form_cache.h" 5 #include "components/autofill/content/renderer/form_cache.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "components/autofill/content/renderer/form_autofill_util.h" 10 #include "components/autofill/content/renderer/form_autofill_util.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 74
75 FormCache::~FormCache() { 75 FormCache::~FormCache() {
76 } 76 }
77 77
78 std::vector<FormData> FormCache::ExtractNewForms() { 78 std::vector<FormData> FormCache::ExtractNewForms() {
79 std::vector<FormData> forms; 79 std::vector<FormData> forms;
80 WebDocument document = frame_.document(); 80 WebDocument document = frame_.document();
81 if (document.isNull()) 81 if (document.isNull())
82 return forms; 82 return forms;
83 83
84 initial_checked_state_.clear();
85 initial_select_values_.clear();
84 WebVector<WebFormElement> web_forms; 86 WebVector<WebFormElement> web_forms;
85 document.forms(web_forms); 87 document.forms(web_forms);
86 88
87 // Log an error message for deprecated attributes, but only the first time 89 // Log an error message for deprecated attributes, but only the first time
88 // the form is parsed. 90 // the form is parsed.
89 bool log_deprecation_messages = parsed_forms_.empty(); 91 bool log_deprecation_messages = parsed_forms_.empty();
90 92
91 const ExtractMask extract_mask = 93 const ExtractMask extract_mask =
92 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); 94 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS);
93 95
(...skipping 14 matching lines...) Expand all
108 extract_mask, &form, nullptr)) { 110 extract_mask, &form, nullptr)) {
109 continue; 111 continue;
110 } 112 }
111 113
112 num_fields_seen += form.fields.size(); 114 num_fields_seen += form.fields.size();
113 if (num_fields_seen > kMaxParseableFields) 115 if (num_fields_seen > kMaxParseableFields)
114 return forms; 116 return forms;
115 117
116 if (form.fields.size() >= kRequiredAutofillFields && 118 if (form.fields.size() >= kRequiredAutofillFields &&
117 !ContainsKey(parsed_forms_, form)) { 119 !ContainsKey(parsed_forms_, form)) {
120 for (auto it = parsed_forms_.begin(); it != parsed_forms_.end(); ++it) {
121 if (it->SameFormAs(form)) {
122 parsed_forms_.erase(it);
123 break;
124 }
125 }
126
127 SaveInitialValues(control_elements);
118 forms.push_back(form); 128 forms.push_back(form);
119 parsed_forms_.insert(form); 129 parsed_forms_.insert(form);
120 } 130 }
121 } 131 }
122 132
123 // Look for more parseable fields outside of forms. 133 // Look for more parseable fields outside of forms.
124 std::vector<WebElement> fieldsets; 134 std::vector<WebElement> fieldsets;
125 std::vector<WebFormControlElement> control_elements = 135 std::vector<WebFormControlElement> control_elements =
126 GetUnownedAutofillableFormFieldElements(document.all(), &fieldsets); 136 GetUnownedAutofillableFormFieldElements(document.all(), &fieldsets);
127 137
128 size_t num_editable_elements = 138 size_t num_editable_elements =
129 ScanFormControlElements(control_elements, log_deprecation_messages); 139 ScanFormControlElements(control_elements, log_deprecation_messages);
130 140
131 if (ShouldIgnoreForm(num_editable_elements, control_elements.size())) 141 if (ShouldIgnoreForm(num_editable_elements, control_elements.size()))
132 return forms; 142 return forms;
133 143
134 FormData synthetic_form; 144 FormData synthetic_form;
135 if (!UnownedFormElementsAndFieldSetsToFormData( 145 if (!UnownedFormElementsAndFieldSetsToFormData(
136 fieldsets, control_elements, nullptr, document, extract_mask, 146 fieldsets, control_elements, nullptr, document, extract_mask,
137 &synthetic_form, nullptr)) { 147 &synthetic_form, nullptr)) {
138 return forms; 148 return forms;
139 } 149 }
140 150
141 num_fields_seen += synthetic_form.fields.size(); 151 num_fields_seen += synthetic_form.fields.size();
142 if (num_fields_seen > kMaxParseableFields) 152 if (num_fields_seen > kMaxParseableFields)
143 return forms; 153 return forms;
144 154
145 if (synthetic_form.fields.size() >= kRequiredAutofillFields && 155 if (synthetic_form.fields.size() >= kRequiredAutofillFields &&
146 !parsed_forms_.count(synthetic_form)) { 156 !parsed_forms_.count(synthetic_form)) {
157 SaveInitialValues(control_elements);
147 forms.push_back(synthetic_form); 158 forms.push_back(synthetic_form);
148 parsed_forms_.insert(synthetic_form); 159 parsed_forms_.insert(synthetic_form);
160 parsed_forms_.erase(synthetic_form_);
149 synthetic_form_ = synthetic_form; 161 synthetic_form_ = synthetic_form;
150 } 162 }
151 return forms; 163 return forms;
152 } 164 }
153 165
154 void FormCache::Reset() { 166 void FormCache::Reset() {
155 synthetic_form_ = FormData(); 167 synthetic_form_ = FormData();
156 parsed_forms_.clear(); 168 parsed_forms_.clear();
157 initial_select_values_.clear(); 169 initial_select_values_.clear();
158 initial_checked_state_.clear(); 170 initial_checked_state_.clear();
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 bool log_deprecation_messages) { 304 bool log_deprecation_messages) {
293 size_t num_editable_elements = 0; 305 size_t num_editable_elements = 0;
294 for (size_t i = 0; i < control_elements.size(); ++i) { 306 for (size_t i = 0; i < control_elements.size(); ++i) {
295 const WebFormControlElement& element = control_elements[i]; 307 const WebFormControlElement& element = control_elements[i];
296 308
297 if (log_deprecation_messages) 309 if (log_deprecation_messages)
298 LogDeprecationMessages(element); 310 LogDeprecationMessages(element);
299 311
300 // Save original values of <select> elements so we can restore them 312 // Save original values of <select> elements so we can restore them
301 // when |ClearFormWithNode()| is invoked. 313 // when |ClearFormWithNode()| is invoked.
314 if (IsSelectElement(element) || IsTextAreaElement(element)) {
315 ++num_editable_elements;
316 } else {
317 const WebInputElement input_element = element.toConst<WebInputElement>();
318 if (!IsCheckableElement(&input_element))
319 ++num_editable_elements;
320 }
321 }
322 return num_editable_elements;
323 }
324
325 void FormCache::SaveInitialValues(
326 const std::vector<WebFormControlElement>& control_elements) {
327 for (const WebFormControlElement& element : control_elements) {
302 if (IsSelectElement(element)) { 328 if (IsSelectElement(element)) {
303 const WebSelectElement select_element = 329 const WebSelectElement select_element =
304 element.toConst<WebSelectElement>(); 330 element.toConst<WebSelectElement>();
305 initial_select_values_.insert( 331 initial_select_values_.insert(
306 std::make_pair(select_element, select_element.value())); 332 std::make_pair(select_element, select_element.value()));
307 ++num_editable_elements;
308 } else if (IsTextAreaElement(element)) {
309 ++num_editable_elements;
310 } else { 333 } else {
311 const WebInputElement input_element = 334 const WebInputElement* input_element = toWebInputElement(&element);
312 element.toConst<WebInputElement>(); 335 if (IsCheckableElement(input_element)) {
313 if (IsCheckableElement(&input_element)) {
314 initial_checked_state_.insert( 336 initial_checked_state_.insert(
315 std::make_pair(input_element, input_element.isChecked())); 337 std::make_pair(*input_element, input_element->isChecked()));
316 } else {
317 ++num_editable_elements;
318 } 338 }
319 } 339 }
320 } 340 }
321 return num_editable_elements;
322 } 341 }
323 342
324 } // namespace autofill 343 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/content/renderer/form_cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698