| Index: chrome/browser/prefs/pref_hash_store_impl.cc
|
| diff --git a/chrome/browser/prefs/pref_hash_store_impl.cc b/chrome/browser/prefs/pref_hash_store_impl.cc
|
| index 4f6f6d6754beddc52616934a6156f4cf9dd425fb..afe2dd10c3c372550df362658d2fde9e848accad 100644
|
| --- a/chrome/browser/prefs/pref_hash_store_impl.cc
|
| +++ b/chrome/browser/prefs/pref_hash_store_impl.cc
|
| @@ -10,29 +10,13 @@
|
| #include "chrome/browser/prefs/pref_hash_store_transaction.h"
|
| #include "chrome/browser/prefs/tracked/hash_store_contents.h"
|
|
|
| -namespace {
|
| -
|
| -// Returns true if the dictionary of hashes stored in |contents| is trusted
|
| -// (which implies unknown values can be trusted as newly tracked values).
|
| -bool IsHashDictionaryTrusted(const PrefHashCalculator& calculator,
|
| - const HashStoreContents& contents) {
|
| - const base::DictionaryValue* store_contents = contents.GetContents();
|
| - std::string super_mac = contents.GetSuperMac();
|
| - // The store must be initialized and have a valid super MAC to be trusted.
|
| - return store_contents && !super_mac.empty() &&
|
| - calculator.Validate(contents.hash_store_id(),
|
| - store_contents,
|
| - super_mac) == PrefHashCalculator::VALID;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| class PrefHashStoreImpl::PrefHashStoreTransactionImpl
|
| : public PrefHashStoreTransaction {
|
| public:
|
| // Constructs a PrefHashStoreTransactionImpl which can use the private
|
| // members of its |outer| PrefHashStoreImpl.
|
| - explicit PrefHashStoreTransactionImpl(PrefHashStoreImpl* outer);
|
| + PrefHashStoreTransactionImpl(PrefHashStoreImpl* outer,
|
| + scoped_ptr<HashStoreContents> storage);
|
| virtual ~PrefHashStoreTransactionImpl();
|
|
|
| // PrefHashStoreTransaction implementation.
|
| @@ -47,86 +31,110 @@ class PrefHashStoreImpl::PrefHashStoreTransactionImpl
|
| virtual void StoreSplitHash(
|
| const std::string& path,
|
| const base::DictionaryValue* split_value) OVERRIDE;
|
| + virtual bool HasHash(const std::string& path) const OVERRIDE;
|
| + virtual void ImportHash(const std::string& path,
|
| + const base::Value* hash) OVERRIDE;
|
| + virtual void ClearHash(const std::string& path) OVERRIDE;
|
| + virtual bool IsSuperMACValid() const OVERRIDE;
|
| + virtual bool StampSuperMac() OVERRIDE;
|
|
|
| private:
|
| bool GetSplitMacs(const std::string& path,
|
| std::map<std::string, std::string>* split_macs) const;
|
| +
|
| + HashStoreContents* contents() {
|
| + return outer_->legacy_hash_store_contents_
|
| + ? outer_->legacy_hash_store_contents_.get()
|
| + : contents_.get();
|
| + }
|
| +
|
| + const HashStoreContents* contents() const {
|
| + return outer_->legacy_hash_store_contents_
|
| + ? outer_->legacy_hash_store_contents_.get()
|
| + : contents_.get();
|
| + }
|
| +
|
| PrefHashStoreImpl* outer_;
|
| - bool has_changed_;
|
| + scoped_ptr<HashStoreContents> contents_;
|
| +
|
| + bool super_mac_valid_;
|
| + bool super_mac_dirty_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(PrefHashStoreTransactionImpl);
|
| };
|
|
|
| PrefHashStoreImpl::PrefHashStoreImpl(const std::string& seed,
|
| const std::string& device_id,
|
| - scoped_ptr<HashStoreContents> contents,
|
| bool use_super_mac)
|
| : pref_hash_calculator_(seed, device_id),
|
| - contents_(contents.Pass()),
|
| - initial_hashes_dictionary_trusted_(
|
| - use_super_mac
|
| - ? IsHashDictionaryTrusted(pref_hash_calculator_, *contents_)
|
| - : false),
|
| - use_super_mac_(use_super_mac),
|
| - has_pending_write_(false) {
|
| - DCHECK(contents_);
|
| - UMA_HISTOGRAM_BOOLEAN("Settings.HashesDictionaryTrusted",
|
| - initial_hashes_dictionary_trusted_);
|
| + use_super_mac_(use_super_mac) {
|
| }
|
|
|
| -PrefHashStoreImpl::~PrefHashStoreImpl() {}
|
| -
|
| -void PrefHashStoreImpl::Reset() {
|
| - contents_->Reset();
|
| +PrefHashStoreImpl::~PrefHashStoreImpl() {
|
| }
|
|
|
| -scoped_ptr<PrefHashStoreTransaction> PrefHashStoreImpl::BeginTransaction() {
|
| - return scoped_ptr<PrefHashStoreTransaction>(
|
| - new PrefHashStoreTransactionImpl(this));
|
| +void PrefHashStoreImpl::set_legacy_hash_store_contents(
|
| + scoped_ptr<HashStoreContents> legacy_hash_store_contents) {
|
| + legacy_hash_store_contents_ = legacy_hash_store_contents.Pass();
|
| }
|
|
|
| -void PrefHashStoreImpl::CommitPendingWrite() {
|
| - if (has_pending_write_) {
|
| - contents_->CommitPendingWrite();
|
| - has_pending_write_ = false;
|
| - }
|
| +scoped_ptr<PrefHashStoreTransaction> PrefHashStoreImpl::BeginTransaction(
|
| + scoped_ptr<HashStoreContents> storage) {
|
| + return scoped_ptr<PrefHashStoreTransaction>(
|
| + new PrefHashStoreTransactionImpl(this, storage.Pass()));
|
| }
|
|
|
| PrefHashStoreImpl::PrefHashStoreTransactionImpl::PrefHashStoreTransactionImpl(
|
| - PrefHashStoreImpl* outer) : outer_(outer), has_changed_(false) {
|
| + PrefHashStoreImpl* outer,
|
| + scoped_ptr<HashStoreContents> storage)
|
| + : outer_(outer),
|
| + contents_(storage.Pass()),
|
| + super_mac_valid_(false),
|
| + super_mac_dirty_(false) {
|
| + if (!outer_->use_super_mac_)
|
| + return;
|
| +
|
| + // The store must be initialized and have a valid super MAC to be trusted.
|
| +
|
| + const base::DictionaryValue* store_contents = contents()->GetContents();
|
| + if (!store_contents)
|
| + return;
|
| +
|
| + std::string super_mac = contents()->GetSuperMac();
|
| + if (super_mac.empty())
|
| + return;
|
| +
|
| + super_mac_valid_ =
|
| + outer_->pref_hash_calculator_.Validate(
|
| + contents()->hash_store_id(), store_contents, super_mac) ==
|
| + PrefHashCalculator::VALID;
|
| }
|
|
|
| PrefHashStoreImpl::PrefHashStoreTransactionImpl::
|
| ~PrefHashStoreTransactionImpl() {
|
| - // Update the super MAC if and only if the hashes dictionary has been
|
| - // modified in this transaction.
|
| - if (has_changed_) {
|
| - if (outer_->use_super_mac_) {
|
| - // Get the dictionary of hashes (or NULL if it doesn't exist).
|
| - const base::DictionaryValue* hashes_dict =
|
| - outer_->contents_->GetContents();
|
| - outer_->contents_->SetSuperMac(outer_->pref_hash_calculator_.Calculate(
|
| - outer_->contents_->hash_store_id(), hashes_dict));
|
| - }
|
| - outer_->has_pending_write_ = true;
|
| + if (super_mac_dirty_ && outer_->use_super_mac_) {
|
| + // Get the dictionary of hashes (or NULL if it doesn't exist).
|
| + const base::DictionaryValue* hashes_dict = contents()->GetContents();
|
| + contents()->SetSuperMac(outer_->pref_hash_calculator_.Calculate(
|
| + contents()->hash_store_id(), hashes_dict));
|
| }
|
| -
|
| }
|
|
|
| PrefHashStoreTransaction::ValueState
|
| PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckValue(
|
| - const std::string& path, const base::Value* initial_value) const {
|
| - const base::DictionaryValue* hashed_prefs = outer_->contents_->GetContents();
|
| + const std::string& path,
|
| + const base::Value* initial_value) const {
|
| + const base::DictionaryValue* hashes_dict = contents()->GetContents();
|
|
|
| std::string last_hash;
|
| - if (hashed_prefs)
|
| - hashed_prefs->GetString(path, &last_hash);
|
| + if (hashes_dict)
|
| + hashes_dict->GetString(path, &last_hash);
|
|
|
| if (last_hash.empty()) {
|
| // In the absence of a hash for this pref, always trust a NULL value, but
|
| // only trust an existing value if the initial hashes dictionary is trusted.
|
| - return (!initial_value || outer_->initial_hashes_dictionary_trusted_) ?
|
| - TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE;
|
| + return (!initial_value || super_mac_valid_) ? TRUSTED_UNKNOWN_VALUE
|
| + : UNTRUSTED_UNKNOWN_VALUE;
|
| }
|
|
|
| PrefHashCalculator::ValidationResult validation_result =
|
| @@ -147,11 +155,12 @@ PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckValue(
|
| }
|
|
|
| void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreHash(
|
| - const std::string& path, const base::Value* new_value) {
|
| + const std::string& path,
|
| + const base::Value* new_value) {
|
| const std::string mac =
|
| outer_->pref_hash_calculator_.Calculate(path, new_value);
|
| - (*outer_->contents_->GetMutableContents())->SetString(path, mac);
|
| - has_changed_ = true;
|
| + (*contents()->GetMutableContents())->SetString(path, mac);
|
| + super_mac_dirty_ = true;
|
| }
|
|
|
| PrefHashStoreTransaction::ValueState
|
| @@ -171,10 +180,8 @@ PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckSplitValue(
|
| if (!initial_split_value || initial_split_value->empty())
|
| return has_hashes ? CLEARED : UNCHANGED;
|
|
|
| - if (!has_hashes) {
|
| - return outer_->initial_hashes_dictionary_trusted_ ?
|
| - TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE;
|
| - }
|
| + if (!has_hashes)
|
| + return super_mac_valid_ ? TRUSTED_UNKNOWN_VALUE : UNTRUSTED_UNKNOWN_VALUE;
|
|
|
| bool has_secure_legacy_id_hashes = false;
|
| std::string keyed_path(path);
|
| @@ -226,15 +233,15 @@ PrefHashStoreImpl::PrefHashStoreTransactionImpl::CheckSplitValue(
|
| }
|
|
|
| return invalid_keys->empty()
|
| - ? (has_secure_legacy_id_hashes ? SECURE_LEGACY : UNCHANGED)
|
| - : CHANGED;
|
| + ? (has_secure_legacy_id_hashes ? SECURE_LEGACY : UNCHANGED)
|
| + : CHANGED;
|
| }
|
|
|
| void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreSplitHash(
|
| const std::string& path,
|
| const base::DictionaryValue* split_value) {
|
| scoped_ptr<HashStoreContents::MutableDictionary> mutable_dictionary =
|
| - outer_->contents_->GetMutableContents();
|
| + contents()->GetMutableContents();
|
| (*mutable_dictionary)->Remove(path, NULL);
|
|
|
| if (split_value) {
|
| @@ -251,7 +258,7 @@ void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreSplitHash(
|
| outer_->pref_hash_calculator_.Calculate(keyed_path, &it.value()));
|
| }
|
| }
|
| - has_changed_ = true;
|
| + super_mac_dirty_ = true;
|
| }
|
|
|
| bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs(
|
| @@ -260,9 +267,9 @@ bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs(
|
| DCHECK(split_macs);
|
| DCHECK(split_macs->empty());
|
|
|
| - const base::DictionaryValue* hashed_prefs = outer_->contents_->GetContents();
|
| + const base::DictionaryValue* hashes_dict = contents()->GetContents();
|
| const base::DictionaryValue* split_mac_dictionary = NULL;
|
| - if (!hashed_prefs || !hashed_prefs->GetDictionary(key, &split_mac_dictionary))
|
| + if (!hashes_dict || !hashes_dict->GetDictionary(key, &split_mac_dictionary))
|
| return false;
|
| for (base::DictionaryValue::Iterator it(*split_mac_dictionary); !it.IsAtEnd();
|
| it.Advance()) {
|
| @@ -275,3 +282,39 @@ bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs(
|
| }
|
| return true;
|
| }
|
| +
|
| +bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::HasHash(
|
| + const std::string& path) const {
|
| + const base::DictionaryValue* hashes_dict = contents()->GetContents();
|
| + return hashes_dict && hashes_dict->Get(path, NULL);
|
| +}
|
| +
|
| +void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ImportHash(
|
| + const std::string& path,
|
| + const base::Value* hash) {
|
| + DCHECK(hash);
|
| +
|
| + (*contents()->GetMutableContents())->Set(path, hash->DeepCopy());
|
| +
|
| + if (super_mac_valid_)
|
| + super_mac_dirty_ = true;
|
| +}
|
| +
|
| +void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ClearHash(
|
| + const std::string& path) {
|
| + if ((*contents()->GetMutableContents())->RemovePath(path, NULL) &&
|
| + super_mac_valid_) {
|
| + super_mac_dirty_ = true;
|
| + }
|
| +}
|
| +
|
| +bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::IsSuperMACValid() const {
|
| + return super_mac_valid_;
|
| +}
|
| +
|
| +bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::StampSuperMac() {
|
| + if (!outer_->use_super_mac_ || super_mac_valid_)
|
| + return false;
|
| + super_mac_dirty_ = true;
|
| + return true;
|
| +}
|
|
|