Index: chrome/browser/content_settings/content_settings_pref_provider.cc |
diff --git a/chrome/browser/content_settings/content_settings_pref_provider.cc b/chrome/browser/content_settings/content_settings_pref_provider.cc |
index c7fe7fdcdc13715573fbf2f236926aa08a0cee62..46507d7b73f4e189193d48eba689d10f3b9cf4a9 100644 |
--- a/chrome/browser/content_settings/content_settings_pref_provider.cc |
+++ b/chrome/browser/content_settings/content_settings_pref_provider.cc |
@@ -30,6 +30,8 @@ |
namespace { |
+typedef std::pair<std::string, std::string> StringPair; |
+ |
// The preference keys where resource identifiers are stored for |
// ContentSettingsType values that support resource identifiers. |
const char* kResourceTypeNames[] = { |
@@ -964,42 +966,93 @@ void PrefProvider::MigrateObsoletePopupsPref() { |
void PrefProvider::MigrateObsoleteContentSettingsPatternPref() { |
if (prefs_->HasPrefPath(prefs::kContentSettingsPatterns) && !is_incognito_) { |
- const DictionaryValue* all_settings_dictionary = |
+ const DictionaryValue* patterns_dictionary = |
prefs_->GetDictionary(prefs::kContentSettingsPatterns); |
- DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs); |
- DictionaryValue* exceptions_dictionary; |
- exceptions_dictionary = update.Get(); |
- for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys()); |
- i != all_settings_dictionary->end_keys(); |
- ++i) { |
- const std::string& key(*i); |
- if (key.empty()) |
- continue; |
+ // A list with invalid keys that will be removed. |
+ std::list<std::string> keys_to_remove; |
+ std::list<StringPair> keys_to_swap; |
- // Validate pattern string and skip it if it is invalid. |
- std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair = |
- ParsePatternString(key); |
- const ContentSettingsPattern& primary_pattern = pattern_pair.first; |
- if (!primary_pattern.IsValid()) { |
- LOG(DFATAL) << "Invalid pattern strings: " << key; |
- continue; |
- } |
+ { |
+ DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs); |
+ DictionaryValue* pattern_pairs_dictionary = update.Get(); |
+ for (DictionaryValue::key_iterator i( |
+ patterns_dictionary->begin_keys()); |
+ i != patterns_dictionary->end_keys(); |
+ ++i) { |
+ const std::string& key(*i); |
+ // Remove broken pattern keys and fix keys with pattern pairs. |
+ size_t sep_pos = key.find(","); |
+ ContentSettingsPattern primary_pattern; |
+ if (sep_pos != std::string::npos) { |
+ primary_pattern = |
+ ContentSettingsPattern::FromString(key.substr(0, sep_pos)); |
+ } else { |
+ primary_pattern = ContentSettingsPattern::FromString(key); |
Bernhard Bauer
2011/08/03 14:53:41
You could actually simplify this to always use |ke
markusheintz_
2011/08/03 21:42:28
Done.
|
+ } |
- // Copy dictionary value. |
- // Get old settings. |
- DictionaryValue* dictionary = NULL; |
- bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( |
- key, &dictionary); |
- DCHECK(found); |
+ // Save the key if it contains a invalid patterns to remove it later. |
+ // Continue and don't try to migrate the broken pattern key. |
+ if (!primary_pattern.IsValid()) { |
+ keys_to_remove.push_back(key); |
+ continue; |
+ } |
- // Create new dictionary key. |
- std::string new_pattern_str = CreatePatternString( |
- primary_pattern, ContentSettingsPattern::Wildcard()); |
+ // If the key contains a pattern pair, then remove the secondary |
+ // pattern from the key. |
+ if (sep_pos != std::string::npos) { |
+ // If the dictionary already has a key that equals the primary pattern |
+ // of the corrupted pattern pair key, don't fix the key but remove it. |
+ if (patterns_dictionary->HasKey(primary_pattern.ToString())) { |
+ keys_to_remove.push_back(key); |
+ continue; |
+ } |
- // Existing values are overwritten. |
- exceptions_dictionary->SetWithoutPathExpansion( |
- new_pattern_str, dictionary->DeepCopy()); |
+ // If there is more than one key with a pattern pair that has the same |
+ // valid primary pattern, then the value of the last key processed |
+ // will win and overwrite the value any previous key. |
+ keys_to_swap.push_back(std::make_pair(key, |
+ primary_pattern.ToString())); |
+ } |
+ |
+ // Copy dictionary value. |
+ DictionaryValue* dictionary = NULL; |
+ bool found = patterns_dictionary->GetDictionaryWithoutPathExpansion( |
+ key, &dictionary); |
+ DCHECK(found); |
+ std::string new_key = CreatePatternString( |
+ primary_pattern, ContentSettingsPattern::Wildcard()); |
+ // Existing values are overwritten. |
+ pattern_pairs_dictionary->SetWithoutPathExpansion( |
+ new_key, dictionary->DeepCopy()); |
+ } |
+ } |
+ |
+ { |
+ DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatterns); |
+ DictionaryValue* mutable_patterns_dictionary = update.Get(); |
+ // Fix broken pattern strings. |
+ for (std::list<StringPair>::iterator i(keys_to_swap.begin()); |
+ i != keys_to_swap.end(); |
+ ++i) { |
+ const StringPair& pattern_str_pair(*i); |
+ Value* dict; |
+ bool found = mutable_patterns_dictionary->RemoveWithoutPathExpansion( |
+ pattern_str_pair.first, &dict); |
+ DCHECK(found); |
+ mutable_patterns_dictionary->SetWithoutPathExpansion( |
+ pattern_str_pair.second, dict); |
+ } |
+ |
+ // Remove settings for invalid pattern strings (keys). |
+ for (std::list<std::string>::iterator i(keys_to_remove.begin()); |
+ i != keys_to_remove.end(); |
+ ++i) { |
+ const std::string& key(*i); |
+ bool found = |
+ mutable_patterns_dictionary->RemoveWithoutPathExpansion(key, NULL); |
+ DCHECK(found); |
+ } |
} |
} |
} |