diff options
author | thomasvl@chromium.org <thomasvl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-08 14:40:53 +0000 |
---|---|---|
committer | thomasvl@chromium.org <thomasvl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-08 14:40:53 +0000 |
commit | ce0a501326e20c17e76796f550179a49be67bc0f (patch) | |
tree | a620ad1268f1313da9fda613ef1c2822087d4c82 /chrome | |
parent | a39aa53a7acabb03a86a5be5c663d6ae47215440 (diff) | |
download | chromium_src-ce0a501326e20c17e76796f550179a49be67bc0f.zip chromium_src-ce0a501326e20c17e76796f550179a49be67bc0f.tar.gz chromium_src-ce0a501326e20c17e76796f550179a49be67bc0f.tar.bz2 |
Putting this back in since it didn't solve the failures.
Revert 49164 - Backing this out to see if it fixes the failures on the two windows bots (landed about when they started).
Revert 49030 AutoFill: Don't save credit card numbers from Autocomplete to the WebDB.
BUG=8026
TEST=AutocompleteHistoryManagerTest
Review URL: http://codereview.chromium.org/2676003
TBR=jhawkins@chromium.org
Review URL: http://codereview.chromium.org/2748002
TBR=thomasvl@chromium.org
Review URL: http://codereview.chromium.org/2770001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49165 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/autocomplete_history_manager.cc | 95 | ||||
-rw-r--r-- | chrome/browser/autocomplete_history_manager.h | 14 | ||||
-rw-r--r-- | chrome/browser/autocomplete_history_manager_unittest.cc | 86 | ||||
-rw-r--r-- | chrome/browser/autofill/credit_card.cc | 52 | ||||
-rw-r--r-- | chrome/browser/autofill/credit_card.h | 7 | ||||
-rw-r--r-- | chrome/browser/webdata/web_data_service.h | 2 | ||||
-rwxr-xr-x | chrome/chrome_tests.gypi | 1 |
7 files changed, 176 insertions, 81 deletions
diff --git a/chrome/browser/autocomplete_history_manager.cc b/chrome/browser/autocomplete_history_manager.cc index e5d96a7..d94f920 100644 --- a/chrome/browser/autocomplete_history_manager.cc +++ b/chrome/browser/autocomplete_history_manager.cc @@ -6,7 +6,9 @@ #include <vector> +#include "base/string16.h" #include "base/string_util.h" +#include "chrome/browser/autofill/credit_card.h" #include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_view_host.h" @@ -16,38 +18,34 @@ using webkit_glue::FormData; +namespace { + // Limit on the number of suggestions to appear in the pop-up menu under an // text input element in a form. -static const int kMaxAutofillMenuItems = 6; +const int kMaxAutocompleteMenuItems = 6; + +// The separator characters for credit card values. +const string16 kCreditCardSeparators = ASCIIToUTF16(" -"); + +} // namespace AutocompleteHistoryManager::AutocompleteHistoryManager( TabContents* tab_contents) : tab_contents_(tab_contents), pending_query_handle_(0), query_id_(0) { - form_autofill_enabled_.Init(prefs::kAutoFillEnabled, - profile()->GetPrefs(), NULL); -} + DCHECK(tab_contents); -AutocompleteHistoryManager::~AutocompleteHistoryManager() { - CancelPendingQuery(); -} + profile_ = tab_contents_->profile(); + DCHECK(profile_); -void AutocompleteHistoryManager::CancelPendingQuery() { - if (pending_query_handle_) { - SendSuggestions(NULL); - WebDataService* web_data_service = - profile()->GetWebDataService(Profile::EXPLICIT_ACCESS); - if (!web_data_service) { - NOTREACHED(); - return; - } - web_data_service->CancelRequest(pending_query_handle_); - } - pending_query_handle_ = 0; + web_data_service_ = profile_->GetWebDataService(Profile::EXPLICIT_ACCESS); + DCHECK(web_data_service_); + + autofill_enabled_.Init(prefs::kAutoFillEnabled, profile_->GetPrefs(), NULL); } -Profile* AutocompleteHistoryManager::profile() { - return tab_contents_->profile(); +AutocompleteHistoryManager::~AutocompleteHistoryManager() { + CancelPendingQuery(); } void AutocompleteHistoryManager::FormSubmitted(const FormData& form) { @@ -56,35 +54,20 @@ void AutocompleteHistoryManager::FormSubmitted(const FormData& form) { bool AutocompleteHistoryManager::GetAutocompleteSuggestions( int query_id, const string16& name, const string16& prefix) { - if (!*form_autofill_enabled_) + if (!*autofill_enabled_) return false; - WebDataService* web_data_service = - profile()->GetWebDataService(Profile::EXPLICIT_ACCESS); - if (!web_data_service) { - NOTREACHED(); - return false; - } - CancelPendingQuery(); query_id_ = query_id; - - pending_query_handle_ = web_data_service->GetFormValuesForElementName( - name, prefix, kMaxAutofillMenuItems, this); + pending_query_handle_ = web_data_service_->GetFormValuesForElementName( + name, prefix, kMaxAutocompleteMenuItems, this); return true; } void AutocompleteHistoryManager::RemoveAutocompleteEntry( const string16& name, const string16& value) { - WebDataService* web_data_service = - profile()->GetWebDataService(Profile::EXPLICIT_ACCESS); - if (!web_data_service) { - NOTREACHED(); - return; - } - - web_data_service->RemoveFormValueForElementName(name, value); + web_data_service_->RemoveFormValueForElementName(name, value); } void AutocompleteHistoryManager::OnWebDataServiceRequestDone( @@ -93,7 +76,7 @@ void AutocompleteHistoryManager::OnWebDataServiceRequestDone( DCHECK(pending_query_handle_); pending_query_handle_ = 0; - if (*form_autofill_enabled_) { + if (*autofill_enabled_) { DCHECK(result); SendSuggestions(result); } else { @@ -101,35 +84,57 @@ void AutocompleteHistoryManager::OnWebDataServiceRequestDone( } } +AutocompleteHistoryManager::AutocompleteHistoryManager( + Profile* profile, WebDataService* wds) : tab_contents_(NULL), + profile_(profile), + web_data_service_(wds), + pending_query_handle_(0), + query_id_(0) { + autofill_enabled_.Init( + prefs::kAutoFillEnabled, profile_->GetPrefs(), NULL); +} + +void AutocompleteHistoryManager::CancelPendingQuery() { + if (pending_query_handle_) { + SendSuggestions(NULL); + web_data_service_->CancelRequest(pending_query_handle_); + } + pending_query_handle_ = 0; +} + void AutocompleteHistoryManager::StoreFormEntriesInWebDatabase( const FormData& form) { - if (!*form_autofill_enabled_) + if (!*autofill_enabled_) return; - if (profile()->IsOffTheRecord()) + if (profile_->IsOffTheRecord()) return; // We put the following restriction on stored FormFields: // - non-empty name // - non-empty value // - text field + // - value is not a credit card number std::vector<webkit_glue::FormField> values; for (std::vector<webkit_glue::FormField>::const_iterator iter = form.fields.begin(); iter != form.fields.end(); ++iter) { if (!iter->value().empty() && !iter->name().empty() && - iter->form_control_type() == ASCIIToUTF16("text")) + iter->form_control_type() == ASCIIToUTF16("text") && + !CreditCard::IsCreditCardNumber(iter->value())) values.push_back(*iter); } - profile()->GetWebDataService(Profile::EXPLICIT_ACCESS)->AddFormFields(values); + if (!values.empty()) + web_data_service_->AddFormFields(values); } void AutocompleteHistoryManager::SendSuggestions(const WDTypedResult* result) { RenderViewHost* host = tab_contents_->render_view_host(); if (!host) return; + if (result) { DCHECK(result->GetType() == AUTOFILL_VALUE_RESULT); const WDResult<std::vector<string16> >* autofill_result = diff --git a/chrome/browser/autocomplete_history_manager.h b/chrome/browser/autocomplete_history_manager.h index 2f8fe5e..4e87bd6 100644 --- a/chrome/browser/autocomplete_history_manager.h +++ b/chrome/browser/autocomplete_history_manager.h @@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_AUTOCOMPLETE_HISTORY_MANAGER_H_ #define CHROME_BROWSER_AUTOCOMPLETE_HISTORY_MANAGER_H_ -#include <string> - #include "chrome/browser/pref_member.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/webdata/web_data_service.h" @@ -27,8 +25,6 @@ class AutocompleteHistoryManager explicit AutocompleteHistoryManager(TabContents* tab_contents); virtual ~AutocompleteHistoryManager(); - Profile* profile(); - // RenderViewHostDelegate::Autocomplete implementation. virtual void FormSubmitted(const webkit_glue::FormData& form); virtual bool GetAutocompleteSuggestions(int query_id, @@ -41,14 +37,22 @@ class AutocompleteHistoryManager virtual void OnWebDataServiceRequestDone(WebDataService::Handle h, const WDTypedResult* result); + protected: + friend class AutocompleteHistoryManagerTest; + + // For tests. + AutocompleteHistoryManager(Profile* profile, WebDataService* wds); + private: void CancelPendingQuery(); void StoreFormEntriesInWebDatabase(const webkit_glue::FormData& form); void SendSuggestions(const WDTypedResult* suggestions); TabContents* tab_contents_; + Profile* profile_; + scoped_refptr<WebDataService> web_data_service_; - BooleanPrefMember form_autofill_enabled_; + BooleanPrefMember autofill_enabled_; // When the manager makes a request from WebDataService, the database // is queried on another thread, we record the query handle until we diff --git a/chrome/browser/autocomplete_history_manager_unittest.cc b/chrome/browser/autocomplete_history_manager_unittest.cc new file mode 100644 index 0000000..49a473c --- /dev/null +++ b/chrome/browser/autocomplete_history_manager_unittest.cc @@ -0,0 +1,86 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "base/ref_counted.h" +#include "base/string16.h" +#include "base/task.h" +#include "chrome/browser/autocomplete_history_manager.h" +#include "chrome/browser/webdata/web_data_service.h" +#include "chrome/test/testing_profile.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/glue/form_data.h" + +using testing::_; +using webkit_glue::FormData; + +class MockWebDataService : public WebDataService { + public: + MOCK_METHOD1(AddFormFields, + void(const std::vector<webkit_glue::FormField>&)); // NOLINT +}; + +class AutocompleteHistoryManagerTest : public testing::Test { + protected: + AutocompleteHistoryManagerTest() + : ui_thread_(ChromeThread::UI, &message_loop_) { + } + + virtual void SetUp() { + web_data_service_ = new MockWebDataService(); + autocomplete_manager_.reset( + new AutocompleteHistoryManager(&profile_, web_data_service_)); + } + + MessageLoopForUI message_loop_; + ChromeThread ui_thread_; + + TestingProfile profile_; + scoped_refptr<MockWebDataService> web_data_service_; + scoped_ptr<AutocompleteHistoryManager> autocomplete_manager_; +}; + +// Tests that credit card numbers are not sent to the WebDatabase to be saved. +TEST_F(AutocompleteHistoryManagerTest, CreditCardNumberValue) { + FormData form; + form.name = ASCIIToUTF16("MyForm"); + form.method = ASCIIToUTF16("POST"); + form.origin = GURL("http://myform.com/form.html"); + form.action = GURL("http://myform.com/submit.html"); + + // Valid Visa credit card number pulled from the paypal help site. + webkit_glue::FormField valid_cc(ASCIIToUTF16("Credit Card"), + ASCIIToUTF16("ccnum"), + ASCIIToUTF16("4012888888881881"), + ASCIIToUTF16("text"), + 20); + form.fields.push_back(valid_cc); + + EXPECT_CALL(*web_data_service_, AddFormFields(_)).Times(0); + autocomplete_manager_->FormSubmitted(form); +} + +// Contrary test to AutocompleteHistoryManagerTest.CreditCardNumberValue. The +// value being submitted is not a valid credit card number, so it will be sent +// to the WebDatabase to be saved. +TEST_F(AutocompleteHistoryManagerTest, NonCreditCardNumberValue) { + FormData form; + form.name = ASCIIToUTF16("MyForm"); + form.method = ASCIIToUTF16("POST"); + form.origin = GURL("http://myform.com/form.html"); + form.action = GURL("http://myform.com/submit.html"); + + // Invalid credit card number. + webkit_glue::FormField invalid_cc(ASCIIToUTF16("Credit Card"), + ASCIIToUTF16("ccnum"), + ASCIIToUTF16("4580123456789012"), + ASCIIToUTF16("text"), + 20); + form.fields.push_back(invalid_cc); + + EXPECT_CALL(*(web_data_service_.get()), AddFormFields(_)).Times(1); + autocomplete_manager_->FormSubmitted(form); +} diff --git a/chrome/browser/autofill/credit_card.cc b/chrome/browser/autofill/credit_card.cc index fefab77..7f41b5e 100644 --- a/chrome/browser/autofill/credit_card.cc +++ b/chrome/browser/autofill/credit_card.cc @@ -281,6 +281,31 @@ bool CreditCard::operator!=(const CreditCard& creditcard) const { return !operator==(creditcard); } +// Use the Luhn formula to validate the number. +bool CreditCard::IsCreditCardNumber(const string16& text) { + string16 number; + RemoveChars(text, kCreditCardSeparators.c_str(), &number); + + int sum = 0; + bool odd = false; + string16::reverse_iterator iter; + for (iter = number.rbegin(); iter != number.rend(); ++iter) { + if (!IsAsciiDigit(*iter)) + return false; + + int digit = *iter - '0'; + if (odd) { + digit *= 2; + sum += digit / 10 + digit % 10; + } else { + sum += digit; + } + odd = !odd; + } + + return (sum % 10) == 0; +} + string16 CreditCard::ExpirationMonthAsString() const { if (expiration_month_ == 0) return string16(); @@ -409,33 +434,6 @@ bool CreditCard::IsNameOnCard(const string16& text) const { return StringToLowerASCII(text) == StringToLowerASCII(name_on_card_); } -bool CreditCard::IsCreditCardNumber(const string16& text) { - string16 number; - TrimString(text, kCreditCardSeparators.c_str(), &number); - - // We use the Luhn formula to validate the number; see - // http://www.beachnet.com/~hstiles/cardtype.html and - // http://www.webopedia.com/TERM/L/Luhn_formula.html. - int sum = 0; - bool odd = false; - string16::reverse_iterator iter; - for (iter = number.rbegin(); iter != number.rend(); ++iter) { - if (!IsAsciiDigit(*iter)) - return false; - - int digit = *iter - '0'; - if (odd) { - digit *= 2; - sum += digit / 10 + digit % 10; - } else { - sum += digit; - } - odd = !odd; - } - - return (sum % 10) == 0; -} - bool CreditCard::IsVerificationCode(const string16& text) const { return StringToLowerASCII(text) == StringToLowerASCII(verification_code_); } diff --git a/chrome/browser/autofill/credit_card.h b/chrome/browser/autofill/credit_card.h index 4c16ec7..50bfa3a 100644 --- a/chrome/browser/autofill/credit_card.h +++ b/chrome/browser/autofill/credit_card.h @@ -58,6 +58,10 @@ class CreditCard : public FormGroup { bool operator!=(const CreditCard& creditcard) const; void set_label(const string16& label) { label_ = label; } + // Returns true if |value| is a credit card number. Uses the Luhn formula to + // validate the number. + static bool IsCreditCardNumber(const string16& text); + private: // The month and year are zero if not present. int Expiration4DigitYear() const { return expiration_year_; } @@ -107,9 +111,6 @@ class CreditCard : public FormGroup { // case-insensitive. bool IsNameOnCard(const string16& text) const; - // Uses the Luhn formula to validate the credit card number in |text|. - static bool IsCreditCardNumber(const string16& text); - // Returns true if |text| matches the expiration month of the card. bool IsExpirationMonth(const string16& text) const; diff --git a/chrome/browser/webdata/web_data_service.h b/chrome/browser/webdata/web_data_service.h index a5105b2..5e35728 100644 --- a/chrome/browser/webdata/web_data_service.h +++ b/chrome/browser/webdata/web_data_service.h @@ -395,7 +395,7 @@ class WebDataService ////////////////////////////////////////////////////////////////////////////// // Schedules a task to add form fields to the web database. - void AddFormFields(const std::vector<webkit_glue::FormField>& fields); + virtual void AddFormFields(const std::vector<webkit_glue::FormField>& fields); // Initiates the request for a vector of values which have been entered in // form input fields named |name|. The method OnWebDataServiceRequestDone of diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index bd1a9fa..83d5f1e 100755 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -541,6 +541,7 @@ # All unittests in browser, common, renderer and service. 'browser/app_controller_mac_unittest.mm', 'browser/app_menu_model_unittest.cc', + 'browser/autocomplete_history_manager_unittest.cc', 'browser/autocomplete/autocomplete_edit_unittest.cc', 'browser/autocomplete/autocomplete_edit_view_mac_unittest.mm', 'browser/autocomplete/autocomplete_popup_view_mac_unittest.mm', |