Chromium Code Reviews| 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); |
| + } |
| } |
| } |
| } |