diff options
author | gcasto@chromium.org <gcasto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-29 23:48:35 +0000 |
---|---|---|
committer | gcasto@chromium.org <gcasto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-29 23:48:35 +0000 |
commit | d3ff31f6d80f3fd21210ebb891cd7265616a63e9 (patch) | |
tree | 08701e8adce2ce050970919bf1723b760ace495f /components | |
parent | d72d0a72ad7875fb761cea7246d154f67e8f501b (diff) | |
download | chromium_src-d3ff31f6d80f3fd21210ebb891cd7265616a63e9.zip chromium_src-d3ff31f6d80f3fd21210ebb891cd7265616a63e9.tar.gz chromium_src-d3ff31f6d80f3fd21210ebb891cd7265616a63e9.tar.bz2 |
[password autofill] Add serialization for FormData and FormFieldData
These objects will soon be added to PasswordForm, which needs to be persisted
by the PasswordStore.
BUG=240559
Review URL: https://chromiumcodereview.appspot.com/23033010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@220437 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components')
-rw-r--r-- | components/autofill/core/common/form_data.cc | 79 | ||||
-rw-r--r-- | components/autofill/core/common/form_data.h | 7 | ||||
-rw-r--r-- | components/autofill/core/common/form_data_unittest.cc | 57 | ||||
-rw-r--r-- | components/autofill/core/common/form_field_data.cc | 106 | ||||
-rw-r--r-- | components/autofill/core/common/form_field_data.h | 11 | ||||
-rw-r--r-- | components/autofill/core/common/form_field_data_unittest.cc | 43 | ||||
-rw-r--r-- | components/components_tests.gypi | 5 |
7 files changed, 307 insertions, 1 deletions
diff --git a/components/autofill/core/common/form_data.cc b/components/autofill/core/common/form_data.cc index e0c3c1c..078a58d 100644 --- a/components/autofill/core/common/form_data.cc +++ b/components/autofill/core/common/form_data.cc @@ -4,10 +4,51 @@ #include "components/autofill/core/common/form_data.h" +#include "base/pickle.h" #include "base/strings/string_util.h" +#include "components/autofill/core/common/form_field_data.h" namespace autofill { +namespace { + +const int kPickleVersion = 1; + +bool ReadGURL(PickleIterator* iter, GURL* url) { + std::string spec; + if (!iter->ReadString(&spec)) + return false; + + *url = GURL(spec); + return true; +} + +void SerializeFormFieldDataVector(const std::vector<FormFieldData> fields, + Pickle* pickle) { + pickle->WriteInt(static_cast<int>(fields.size())); + for (size_t i = 0; i < fields.size(); ++i) { + SerializeFormFieldData(fields[i], pickle); + } +} + +bool DeserializeFormFieldDataVector(PickleIterator* iter, + std::vector<FormFieldData>* fields) { + int size; + if (!iter->ReadInt(&size)) + return false; + + FormFieldData temp; + for (int i = 0; i < size; ++i) { + if (!DeserializeFormFieldData(iter, &temp)) + return false; + + fields->push_back(temp); + } + return true; +} + +} // namespace + FormData::FormData() : user_submitted(false) { } @@ -37,4 +78,42 @@ bool FormData::operator!=(const FormData& form) const { return !operator==(form); } +void SerializeFormData(const FormData& form_data, Pickle* pickle) { + pickle->WriteInt(kPickleVersion); + pickle->WriteString16(form_data.name); + pickle->WriteString16(form_data.method); + pickle->WriteString(form_data.origin.spec()); + pickle->WriteString(form_data.action.spec()); + pickle->WriteBool(form_data.user_submitted); + SerializeFormFieldDataVector(form_data.fields, pickle); +} + +bool DeserializeFormData(PickleIterator* iter, FormData* form_data) { + int version; + if (!iter->ReadInt(&version)) { + LOG(ERROR) << "Bad pickle of FormData, no version present"; + return false; + } + + switch (version) { + case 1: { + if (!iter->ReadString16(&form_data->name) || + !iter->ReadString16(&form_data->method) || + !ReadGURL(iter, &form_data->origin) || + !ReadGURL(iter, &form_data->action) || + !iter->ReadBool(&form_data->user_submitted) || + !DeserializeFormFieldDataVector(iter, &form_data->fields)) { + LOG(ERROR) << "Could not deserialize FormData from pickle"; + return false; + } + break; + } + default: { + LOG(ERROR) << "Unknown FormData pickle version " << version; + return false; + } + } + return true; +} + } // namespace autofill diff --git a/components/autofill/core/common/form_data.h b/components/autofill/core/common/form_data.h index 202fb8d..1d6dffa 100644 --- a/components/autofill/core/common/form_data.h +++ b/components/autofill/core/common/form_data.h @@ -37,6 +37,13 @@ struct FormData { std::vector<FormFieldData> fields; }; +// Serialize FormData. Used by the PasswordManager to persist FormData +// pertaining to password forms. Serialized data is appended to |pickle| +void SerializeFormData(const FormData& form_data, Pickle* pickle); +// Deserialize FormData. This assumes that |iter| is currently pointing to +// the part of a pickle created by SerializeFormData. Returns true on success. +bool DeserializeFormData(PickleIterator* iter, FormData* form_data); + } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_COMMON_FORM_DATA_H__ diff --git a/components/autofill/core/common/form_data_unittest.cc b/components/autofill/core/common/form_data_unittest.cc new file mode 100644 index 0000000..2d4b7aa --- /dev/null +++ b/components/autofill/core/common/form_data_unittest.cc @@ -0,0 +1,57 @@ +// Copyright 2013 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 "components/autofill/core/common/form_data.h" + +#include "base/pickle.h" +#include "base/strings/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { + +TEST(FormDataTest, SerializeAndDeserialize) { + FormData data; + data.name = ASCIIToUTF16("name"); + data.method = ASCIIToUTF16("POST"); + data.origin = GURL("origin"); + data.action = GURL("action"); + data.user_submitted = true; + + FormFieldData field_data; + field_data.label = ASCIIToUTF16("label"); + field_data.name = ASCIIToUTF16("name"); + field_data.value = ASCIIToUTF16("value"); + field_data.form_control_type = "password"; + field_data.autocomplete_attribute = "off"; + field_data.max_length = 200; + field_data.is_autofilled = true; + field_data.is_checked = true; + field_data.is_checkable = true; + field_data.is_focusable = true; + field_data.should_autocomplete = false; + field_data.text_direction = base::i18n::RIGHT_TO_LEFT; + field_data.option_values.push_back(ASCIIToUTF16("First")); + field_data.option_values.push_back(ASCIIToUTF16("Second")); + field_data.option_contents.push_back(ASCIIToUTF16("First")); + field_data.option_contents.push_back(ASCIIToUTF16("Second")); + + data.fields.push_back(field_data); + + // Change a few fields. + field_data.max_length = 150; + field_data.option_values.push_back(ASCIIToUTF16("Third")); + field_data.option_contents.push_back(ASCIIToUTF16("Third")); + data.fields.push_back(field_data); + + Pickle pickle; + SerializeFormData(data, &pickle); + + PickleIterator iter(pickle); + FormData actual; + EXPECT_TRUE(DeserializeFormData(&iter, &actual)); + + EXPECT_EQ(actual, data); +} + +} // namespace autofill diff --git a/components/autofill/core/common/form_field_data.cc b/components/autofill/core/common/form_field_data.cc index 1de786dc..afa9f53 100644 --- a/components/autofill/core/common/form_field_data.cc +++ b/components/autofill/core/common/form_field_data.cc @@ -4,9 +4,59 @@ #include "components/autofill/core/common/form_field_data.h" +#include "base/pickle.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +namespace { + +const int kPickleVersion = 1; + +void AddVectorToPickle(std::vector<base::string16> strings, + Pickle* pickle) { + pickle->WriteInt(static_cast<int>(strings.size())); + for (size_t i = 0; i < strings.size(); ++i) { + pickle->WriteString16(strings[i]); + } +} + +bool ReadStringVector(PickleIterator* iter, + std::vector<base::string16>* strings) { + int size; + if (!iter->ReadInt(&size)) + return false; + + string16 pickle_data; + for (int i = 0; i < size; i++) { + if (!iter->ReadString16(&pickle_data)) + return false; + + strings->push_back(pickle_data); + } + return true; +} + +bool ReadTextDirection(PickleIterator* iter, + base::i18n::TextDirection* direction) { + int pickle_data; + if (!iter->ReadInt(&pickle_data)) + return false; + + *direction = static_cast<base::i18n::TextDirection>(pickle_data); + return true; +} + +bool ReadSize(PickleIterator* iter, size_t* size) { + uint64 pickle_data; + if (!iter->ReadUInt64(&pickle_data)) + return false; + + *size = static_cast<size_t>(pickle_data); + return true; +} + +} // namespace + namespace autofill { FormFieldData::FormFieldData() @@ -43,6 +93,62 @@ bool FormFieldData::operator<(const FormFieldData& field) const { return label < field.label; } +void SerializeFormFieldData(const FormFieldData& field_data, + Pickle* pickle) { + pickle->WriteInt(kPickleVersion); + pickle->WriteString16(field_data.label); + pickle->WriteString16(field_data.name); + pickle->WriteString16(field_data.value); + pickle->WriteString(field_data.form_control_type); + pickle->WriteString(field_data.autocomplete_attribute); + pickle->WriteUInt64(static_cast<uint64>(field_data.max_length)); + pickle->WriteBool(field_data.is_autofilled); + pickle->WriteBool(field_data.is_checked); + pickle->WriteBool(field_data.is_checkable); + pickle->WriteBool(field_data.is_focusable); + pickle->WriteBool(field_data.should_autocomplete); + pickle->WriteInt(field_data.text_direction); + AddVectorToPickle(field_data.option_values, pickle); + AddVectorToPickle(field_data.option_contents, pickle); +} + +bool DeserializeFormFieldData(PickleIterator* iter, + FormFieldData* field_data) { + int version; + if (!iter->ReadInt(&version)) { + LOG(ERROR) << "Bad pickle of FormFieldData, no version present"; + return false; + } + + switch (version) { + case 1: { + if (!iter->ReadString16(&field_data->label) || + !iter->ReadString16(&field_data->name) || + !iter->ReadString16(&field_data->value) || + !iter->ReadString(&field_data->form_control_type) || + !iter->ReadString(&field_data->autocomplete_attribute) || + !ReadSize(iter, &field_data->max_length) || + !iter->ReadBool(&field_data->is_autofilled) || + !iter->ReadBool(&field_data->is_checked) || + !iter->ReadBool(&field_data->is_checkable) || + !iter->ReadBool(&field_data->is_focusable) || + !iter->ReadBool(&field_data->should_autocomplete) || + !ReadTextDirection(iter, &field_data->text_direction) || + !ReadStringVector(iter, &field_data->option_values) || + !ReadStringVector(iter, &field_data->option_contents)) { + LOG(ERROR) << "Could not deserialize FormFieldData from pickle"; + return false; + } + break; + } + default: { + LOG(ERROR) << "Unknown FormFieldData pickle version " << version; + return false; + } + } + return true; +} + std::ostream& operator<<(std::ostream& os, const FormFieldData& field) { return os << UTF16ToUTF8(field.label) diff --git a/components/autofill/core/common/form_field_data.h b/components/autofill/core/common/form_field_data.h index f0e7579..1bf163e 100644 --- a/components/autofill/core/common/form_field_data.h +++ b/components/autofill/core/common/form_field_data.h @@ -10,6 +10,9 @@ #include "base/i18n/rtl.h" #include "base/strings/string16.h" +class Pickle; +class PickleIterator; + namespace autofill { // Stores information about a field in a form. @@ -45,6 +48,13 @@ struct FormFieldData { std::vector<base::string16> option_contents; }; +// Serialize and deserialize FormFieldData. These are used when FormData objects +// are serialized and deserialized. +void SerializeFormFieldData(const FormFieldData& form_field_data, + Pickle* serialized); +bool DeserializeFormFieldData(PickleIterator* pickle_iterator, + FormFieldData* form_field_data); + // So we can compare FormFieldDatas with EXPECT_EQ(). std::ostream& operator<<(std::ostream& os, const FormFieldData& field); @@ -66,4 +76,3 @@ std::ostream& operator<<(std::ostream& os, const FormFieldData& field); } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_COMMON_FORM_FIELD_DATA_H_ - diff --git a/components/autofill/core/common/form_field_data_unittest.cc b/components/autofill/core/common/form_field_data_unittest.cc new file mode 100644 index 0000000..7f4ef09 --- /dev/null +++ b/components/autofill/core/common/form_field_data_unittest.cc @@ -0,0 +1,43 @@ +// Copyright 2013 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 "components/autofill/core/common/form_field_data.h" + +#include "base/i18n/rtl.h" +#include "base/pickle.h" +#include "base/strings/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { + +TEST(FormFieldDataTest, SerializeAndDeserialize) { + FormFieldData data; + data.label = ASCIIToUTF16("label"); + data.name = ASCIIToUTF16("name"); + data.value = ASCIIToUTF16("value"); + data.form_control_type = "password"; + data.autocomplete_attribute = "off"; + data.max_length = 200; + data.is_autofilled = true; + data.is_checked = true; + data.is_checkable = true; + data.is_focusable = true; + data.should_autocomplete = false; + data.text_direction = base::i18n::RIGHT_TO_LEFT; + data.option_values.push_back(ASCIIToUTF16("First")); + data.option_values.push_back(ASCIIToUTF16("Second")); + data.option_contents.push_back(ASCIIToUTF16("First")); + data.option_contents.push_back(ASCIIToUTF16("Second")); + + Pickle pickle; + SerializeFormFieldData(data, &pickle); + + PickleIterator iter(pickle); + FormFieldData actual; + EXPECT_TRUE(DeserializeFormFieldData(&iter, &actual)); + + EXPECT_EQ(actual, data); +} + +} // namespace autofill diff --git a/components/components_tests.gypi b/components/components_tests.gypi index 1cd55d2..910d2e6 100644 --- a/components/components_tests.gypi +++ b/components/components_tests.gypi @@ -10,6 +10,8 @@ 'target_name': 'components_unittests', 'type': '<(gtest_target_type)', 'sources': [ + 'autofill/core/common/form_data_unittest.cc', + 'autofill/core/common/form_field_data_unittest.cc', 'auto_login_parser/auto_login_parser_unittest.cc', 'browser_context_keyed_service/browser_context_dependency_manager_unittest.cc', 'browser_context_keyed_service/dependency_graph_unittest.cc', @@ -37,6 +39,9 @@ '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', + # Dependencies of autofill + 'autofill_core_common', + # Dependencies of auto_login_parser 'auto_login_parser', |