1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/content_settings/content_settings_utils.h" 6 7 #include <vector> 8 9 #include "base/command_line.h" 10 #include "base/logging.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_vector.h" 13 #include "base/strings/string_split.h" 14 #include "base/values.h" 15 #include "chrome/browser/content_settings/content_settings_provider.h" 16 #include "chrome/browser/content_settings/content_settings_rule.h" 17 #include "chrome/browser/content_settings/host_content_settings_map.h" 18 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/content_settings_pattern.h" 20 #include "url/gurl.h" 21 22 namespace { 23 24 // The names of the ContentSettingsType values, for use with dictionary prefs. 25 const char* kTypeNames[] = { 26 "cookies", 27 "images", 28 "javascript", 29 "plugins", 30 "popups", 31 "geolocation", 32 "notifications", 33 "auto-select-certificate", 34 "fullscreen", 35 "mouselock", 36 "mixed-script", 37 "media-stream", 38 "media-stream-mic", 39 "media-stream-camera", 40 "register-protocol-handler", 41 "ppapi-broker", 42 "multiple-automatic-downloads", 43 "midi-sysex", 44 #if defined(OS_WIN) 45 "metro-switch-to-desktop", 46 #endif 47 }; 48 COMPILE_ASSERT(arraysize(kTypeNames) == CONTENT_SETTINGS_NUM_TYPES, 49 type_names_incorrect_size); 50 51 const char kPatternSeparator[] = ","; 52 53 } // namespace 54 55 namespace content_settings { 56 57 std::string GetTypeName(ContentSettingsType type) { 58 return std::string(kTypeNames[type]); 59 } 60 61 std::string CreatePatternString( 62 const ContentSettingsPattern& item_pattern, 63 const ContentSettingsPattern& top_level_frame_pattern) { 64 return item_pattern.ToString() 65 + std::string(kPatternSeparator) 66 + top_level_frame_pattern.ToString(); 67 } 68 69 PatternPair ParsePatternString(const std::string& pattern_str) { 70 std::vector<std::string> pattern_str_list; 71 base::SplitString(pattern_str, kPatternSeparator[0], &pattern_str_list); 72 73 // If the |pattern_str| is an empty string then the |pattern_string_list| 74 // contains a single empty string. In this case the empty string will be 75 // removed to signal an invalid |pattern_str|. Invalid pattern strings are 76 // handle by the "if"-statment below. So the order of the if statements here 77 // must be preserved. 78 if (pattern_str_list.size() == 1) { 79 if (pattern_str_list[0].empty()) { 80 pattern_str_list.pop_back(); 81 } else { 82 pattern_str_list.push_back("*"); 83 } 84 } 85 86 if (pattern_str_list.size() > 2 || 87 pattern_str_list.size() == 0) { 88 return PatternPair(ContentSettingsPattern(), 89 ContentSettingsPattern()); 90 } 91 92 PatternPair pattern_pair; 93 pattern_pair.first = 94 ContentSettingsPattern::FromString(pattern_str_list[0]); 95 pattern_pair.second = 96 ContentSettingsPattern::FromString(pattern_str_list[1]); 97 return pattern_pair; 98 } 99 100 ContentSetting ValueToContentSetting(const base::Value* value) { 101 ContentSetting setting = CONTENT_SETTING_DEFAULT; 102 bool valid = ParseContentSettingValue(value, &setting); 103 DCHECK(valid); 104 return setting; 105 } 106 107 bool ParseContentSettingValue(const base::Value* value, 108 ContentSetting* setting) { 109 if (!value) { 110 *setting = CONTENT_SETTING_DEFAULT; 111 return true; 112 } 113 int int_value = -1; 114 if (!value->GetAsInteger(&int_value)) 115 return false; 116 *setting = IntToContentSetting(int_value); 117 return *setting != CONTENT_SETTING_DEFAULT; 118 } 119 120 base::Value* GetContentSettingValueAndPatterns( 121 const ProviderInterface* provider, 122 const GURL& primary_url, 123 const GURL& secondary_url, 124 ContentSettingsType content_type, 125 const std::string& resource_identifier, 126 bool include_incognito, 127 ContentSettingsPattern* primary_pattern, 128 ContentSettingsPattern* secondary_pattern) { 129 if (include_incognito) { 130 // Check incognito-only specific settings. It's essential that the 131 // |RuleIterator| gets out of scope before we get a rule iterator for the 132 // normal mode. 133 scoped_ptr<RuleIterator> incognito_rule_iterator( 134 provider->GetRuleIterator(content_type, resource_identifier, true)); 135 base::Value* value = GetContentSettingValueAndPatterns( 136 incognito_rule_iterator.get(), primary_url, secondary_url, 137 primary_pattern, secondary_pattern); 138 if (value) 139 return value; 140 } 141 // No settings from the incognito; use the normal mode. 142 scoped_ptr<RuleIterator> rule_iterator( 143 provider->GetRuleIterator(content_type, resource_identifier, false)); 144 return GetContentSettingValueAndPatterns( 145 rule_iterator.get(), primary_url, secondary_url, 146 primary_pattern, secondary_pattern); 147 } 148 149 base::Value* GetContentSettingValueAndPatterns( 150 RuleIterator* rule_iterator, 151 const GURL& primary_url, 152 const GURL& secondary_url, 153 ContentSettingsPattern* primary_pattern, 154 ContentSettingsPattern* secondary_pattern) { 155 while (rule_iterator->HasNext()) { 156 const Rule& rule = rule_iterator->Next(); 157 if (rule.primary_pattern.Matches(primary_url) && 158 rule.secondary_pattern.Matches(secondary_url)) { 159 if (primary_pattern) 160 *primary_pattern = rule.primary_pattern; 161 if (secondary_pattern) 162 *secondary_pattern = rule.secondary_pattern; 163 return rule.value.get()->DeepCopy(); 164 } 165 } 166 return NULL; 167 } 168 169 base::Value* GetContentSettingValue(const ProviderInterface* provider, 170 const GURL& primary_url, 171 const GURL& secondary_url, 172 ContentSettingsType content_type, 173 const std::string& resource_identifier, 174 bool include_incognito) { 175 return GetContentSettingValueAndPatterns(provider, primary_url, secondary_url, 176 content_type, resource_identifier, 177 include_incognito, NULL, NULL); 178 } 179 180 ContentSetting GetContentSetting(const ProviderInterface* provider, 181 const GURL& primary_url, 182 const GURL& secondary_url, 183 ContentSettingsType content_type, 184 const std::string& resource_identifier, 185 bool include_incognito) { 186 scoped_ptr<base::Value> value( 187 GetContentSettingValue(provider, primary_url, secondary_url, 188 content_type, resource_identifier, 189 include_incognito)); 190 return ValueToContentSetting(value.get()); 191 } 192 193 void GetRendererContentSettingRules(const HostContentSettingsMap* map, 194 RendererContentSettingRules* rules) { 195 map->GetSettingsForOneType( 196 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), &(rules->image_rules)); 197 map->GetSettingsForOneType( 198 CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string(), &(rules->script_rules)); 199 } 200 201 } // namespace content_settings 202