| 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 096cbd9470b739d71403d929c9c5a1d745db16de..2f18adeef8f09e1362f781e997cf1ed3291678ac 100644
|
| --- a/chrome/browser/prefs/pref_hash_store_impl.cc
|
| +++ b/chrome/browser/prefs/pref_hash_store_impl.cc
|
| @@ -10,23 +10,6 @@
|
| #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:
|
| @@ -40,6 +23,12 @@ class PrefHashStoreImpl::PrefHashStoreTransactionImpl
|
| const base::Value* value) const OVERRIDE;
|
| virtual void StoreHash(const std::string& path,
|
| const base::Value* value) OVERRIDE;
|
| + virtual const base::Value* GetHash(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 StampSuperMac() OVERRIDE;
|
| +
|
| virtual ValueState CheckSplitValue(
|
| const std::string& path,
|
| const base::DictionaryValue* initial_split_value,
|
| @@ -53,47 +42,43 @@ class PrefHashStoreImpl::PrefHashStoreTransactionImpl
|
| std::map<std::string, std::string>* split_macs) const;
|
| PrefHashStoreImpl* outer_;
|
| bool has_changed_;
|
| + 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_(
|
| - IsHashDictionaryTrusted(pref_hash_calculator_, *contents_)),
|
| + use_super_mac_(use_super_mac),
|
| + checked_super_mac_(false),
|
| + initial_hashes_dictionary_trusted_(false),
|
| has_pending_write_(false) {
|
| - DCHECK(contents_);
|
| - UMA_HISTOGRAM_BOOLEAN("Settings.HashesDictionaryTrusted",
|
| - initial_hashes_dictionary_trusted_);
|
| }
|
|
|
| PrefHashStoreImpl::~PrefHashStoreImpl() {}
|
|
|
| +void PrefHashStoreImpl::SetHashStoreContents(
|
| + scoped_ptr<HashStoreContents> contents) {
|
| + contents_ = contents.Pass();
|
| +
|
| +}
|
| +
|
| +bool PrefHashStoreImpl::IsInitialized() const {
|
| + return contents_->IsInitialized();
|
| +}
|
| +
|
| void PrefHashStoreImpl::Reset() {
|
| contents_->Reset();
|
| }
|
|
|
| scoped_ptr<PrefHashStoreTransaction> PrefHashStoreImpl::BeginTransaction() {
|
| + CheckSuperMac();
|
| return scoped_ptr<PrefHashStoreTransaction>(
|
| new PrefHashStoreTransactionImpl(this));
|
| }
|
|
|
| -PrefHashStoreImpl::StoreVersion PrefHashStoreImpl::GetCurrentVersion() const {
|
| - if (!contents_->IsInitialized())
|
| - return VERSION_UNINITIALIZED;
|
| -
|
| - int current_version;
|
| - if (!contents_->GetVersion(¤t_version)) {
|
| - return VERSION_PRE_MIGRATION;
|
| - }
|
| -
|
| - DCHECK_GT(current_version, VERSION_PRE_MIGRATION);
|
| - return static_cast<StoreVersion>(current_version);
|
| -}
|
| -
|
| void PrefHashStoreImpl::CommitPendingWrite() {
|
| if (has_pending_write_) {
|
| contents_->CommitPendingWrite();
|
| @@ -101,36 +86,58 @@ void PrefHashStoreImpl::CommitPendingWrite() {
|
| }
|
| }
|
|
|
| +bool PrefHashStoreImpl::CheckSuperMac() {
|
| + if (checked_super_mac_ || !use_super_mac_)
|
| + return initial_hashes_dictionary_trusted_;
|
| +
|
| + 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.
|
| + initial_hashes_dictionary_trusted_ =
|
| + store_contents && !super_mac.empty() &&
|
| + pref_hash_calculator_.Validate(contents_->hash_store_id(),
|
| + store_contents,
|
| + super_mac) == PrefHashCalculator::VALID;
|
| +
|
| + checked_super_mac_ = true;
|
| +
|
| + UMA_HISTOGRAM_BOOLEAN("Settings.HashesDictionaryTrusted",
|
| + initial_hashes_dictionary_trusted_);
|
| +
|
| + return initial_hashes_dictionary_trusted_;
|
| +}
|
| +
|
| PrefHashStoreImpl::PrefHashStoreTransactionImpl::PrefHashStoreTransactionImpl(
|
| - PrefHashStoreImpl* outer) : outer_(outer), has_changed_(false) {
|
| + PrefHashStoreImpl* outer)
|
| + : outer_(outer), has_changed_(false), super_mac_dirty_(false) {
|
| }
|
|
|
| PrefHashStoreImpl::PrefHashStoreTransactionImpl::
|
| ~PrefHashStoreTransactionImpl() {
|
| - // Update the super MAC if and only if the hashes dictionary has been
|
| - // modified in this transaction.
|
| if (has_changed_) {
|
| - // 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));
|
| + // Update the super MAC if and only if the hashes dictionary has been
|
| + // modified in this transaction. Imports do not necessarily affect the super
|
| + // MAC (will not transition it from invalid to valid).
|
| + if (outer_->use_super_mac_ && super_mac_dirty_) {
|
| + // 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;
|
| }
|
| +}
|
|
|
| - // Mark this hash store has having been updated to the latest version (in
|
| - // practice only initialization transactions will actually do this, but
|
| - // since they always occur before minor update transaction it's okay
|
| - // to unconditionally do this here). Only do this if this store's version
|
| - // isn't already at VERSION_LATEST (to avoid scheduling a write when
|
| - // unecessary). Note, this is outside of |if (has_changed)| to also seed
|
| - // version number of otherwise unchanged profiles.
|
| - int current_version;
|
| - if (!outer_->contents_->GetVersion(¤t_version) ||
|
| - current_version != VERSION_LATEST) {
|
| - outer_->contents_->SetVersion(VERSION_LATEST);
|
| - outer_->has_pending_write_ = true;
|
| - }
|
| +const base::Value* PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetHash(
|
| + const std::string& path) const {
|
| + const base::DictionaryValue* hashed_prefs = outer_->contents_->GetContents();
|
| +
|
| + const base::Value* last_hash = NULL;
|
| + if (hashed_prefs)
|
| + hashed_prefs->Get(path, &last_hash);
|
| + return last_hash;
|
| }
|
|
|
| PrefHashStoreTransaction::ValueState
|
| @@ -172,6 +179,35 @@ void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreHash(
|
| outer_->pref_hash_calculator_.Calculate(path, new_value);
|
| (*outer_->contents_->GetMutableContents())->SetString(path, mac);
|
| has_changed_ = true;
|
| + super_mac_dirty_ = true;
|
| +}
|
| +
|
| +void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ImportHash(
|
| + const std::string& path,
|
| + const base::Value* hash) {
|
| + if (!hash)
|
| + (*outer_->contents_->GetMutableContents())->RemovePath(path, NULL);
|
| + else
|
| + (*outer_->contents_->GetMutableContents())->Set(path, hash->DeepCopy());
|
| + has_changed_ = true;
|
| + super_mac_dirty_ =
|
| + super_mac_dirty_ || outer_->initial_hashes_dictionary_trusted_;
|
| +}
|
| +
|
| +void PrefHashStoreImpl::PrefHashStoreTransactionImpl::ClearHash(
|
| + const std::string& path) {
|
| + (*outer_->contents_->GetMutableContents())->RemovePath(path, NULL);
|
| + has_changed_ = true;
|
| + super_mac_dirty_ =
|
| + super_mac_dirty_ || outer_->initial_hashes_dictionary_trusted_;
|
| +}
|
| +
|
| +bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::StampSuperMac() {
|
| + if (!outer_->use_super_mac_ || outer_->initial_hashes_dictionary_trusted_)
|
| + return false;
|
| + has_changed_ = true;
|
| + super_mac_dirty_ = true;
|
| + return true;
|
| }
|
|
|
| PrefHashStoreTransaction::ValueState
|
| @@ -272,6 +308,7 @@ void PrefHashStoreImpl::PrefHashStoreTransactionImpl::StoreSplitHash(
|
| }
|
| }
|
| has_changed_ = true;
|
| + super_mac_dirty_ = true;
|
| }
|
|
|
| bool PrefHashStoreImpl::PrefHashStoreTransactionImpl::GetSplitMacs(
|
|
|