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/host_content_settings_map.h" 16 #include "chrome/common/chrome_switches.h" 17 #include "components/content_settings/core/browser/content_settings_provider.h" 18 #include "components/content_settings/core/browser/content_settings_rule.h" 19 #include "components/content_settings/core/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 "push-messaging", 45 "ssl-cert-decisions", 46 #if defined(OS_WIN) 47 "metro-switch-to-desktop", 48 #elif defined(OS_ANDROID) || defined(OS_CHROMEOS) 49 "protected-media-identifier", 50 #endif 51 #if defined(OS_ANDROID) 52 "app-banner", 53 #endif 54 }; 55 COMPILE_ASSERT(arraysize(kTypeNames) == CONTENT_SETTINGS_NUM_TYPES, 56 type_names_incorrect_size); 57 58 const char kPatternSeparator[] = ","; 59 60 } // namespace 61 62 namespace content_settings { 63 64 std::string GetTypeName(ContentSettingsType type) { 65 return std::string(kTypeNames[type]); 66 } 67 68 bool GetTypeFromName(const std::string& name, 69 ContentSettingsType* return_setting) { 70 for (size_t type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) { 71 if (name.compare(kTypeNames[type]) == 0) { 72 *return_setting = static_cast<ContentSettingsType>(type); 73 return true; 74 } 75 } 76 return false; 77 } 78 79 std::string ContentSettingToString(ContentSetting setting) { 80 switch (setting) { 81 case CONTENT_SETTING_ALLOW: 82 return "allow"; 83 case CONTENT_SETTING_ASK: 84 return "ask"; 85 case CONTENT_SETTING_BLOCK: 86 return "block"; 87 case CONTENT_SETTING_SESSION_ONLY: 88 return "session"; 89 case CONTENT_SETTING_DEFAULT: 90 return "default"; 91 case CONTENT_SETTING_NUM_SETTINGS: 92 NOTREACHED(); 93 } 94 95 return std::string(); 96 } 97 98 ContentSetting ContentSettingFromString(const std::string& name) { 99 if (name == "allow") 100 return CONTENT_SETTING_ALLOW; 101 if (name == "ask") 102 return CONTENT_SETTING_ASK; 103 if (name == "block") 104 return CONTENT_SETTING_BLOCK; 105 if (name == "session") 106 return CONTENT_SETTING_SESSION_ONLY; 107 108 NOTREACHED() << name << " is not a recognized content setting."; 109 return CONTENT_SETTING_DEFAULT; 110 } 111 112 std::string CreatePatternString( 113 const ContentSettingsPattern& item_pattern, 114 const ContentSettingsPattern& top_level_frame_pattern) { 115 return item_pattern.ToString() 116 + std::string(kPatternSeparator) 117 + top_level_frame_pattern.ToString(); 118 } 119 120 PatternPair ParsePatternString(const std::string& pattern_str) { 121 std::vector<std::string> pattern_str_list; 122 base::SplitString(pattern_str, kPatternSeparator[0], &pattern_str_list); 123 124 // If the |pattern_str| is an empty string then the |pattern_string_list| 125 // contains a single empty string. In this case the empty string will be 126 // removed to signal an invalid |pattern_str|. Invalid pattern strings are 127 // handle by the "if"-statment below. So the order of the if statements here 128 // must be preserved. 129 if (pattern_str_list.size() == 1) { 130 if (pattern_str_list[0].empty()) { 131 pattern_str_list.pop_back(); 132 } else { 133 pattern_str_list.push_back("*"); 134 } 135 } 136 137 if (pattern_str_list.size() > 2 || 138 pattern_str_list.size() == 0) { 139 return PatternPair(ContentSettingsPattern(), 140 ContentSettingsPattern()); 141 } 142 143 PatternPair pattern_pair; 144 pattern_pair.first = 145 ContentSettingsPattern::FromString(pattern_str_list[0]); 146 pattern_pair.second = 147 ContentSettingsPattern::FromString(pattern_str_list[1]); 148 return pattern_pair; 149 } 150 151 ContentSetting ValueToContentSetting(const base::Value* value) { 152 ContentSetting setting = CONTENT_SETTING_DEFAULT; 153 bool valid = ParseContentSettingValue(value, &setting); 154 DCHECK(valid); 155 return setting; 156 } 157 158 bool ParseContentSettingValue(const base::Value* value, 159 ContentSetting* setting) { 160 if (!value) { 161 *setting = CONTENT_SETTING_DEFAULT; 162 return true; 163 } 164 int int_value = -1; 165 if (!value->GetAsInteger(&int_value)) 166 return false; 167 *setting = IntToContentSetting(int_value); 168 return *setting != CONTENT_SETTING_DEFAULT; 169 } 170 171 base::Value* GetContentSettingValueAndPatterns( 172 const ProviderInterface* provider, 173 const GURL& primary_url, 174 const GURL& secondary_url, 175 ContentSettingsType content_type, 176 const std::string& resource_identifier, 177 bool include_incognito, 178 ContentSettingsPattern* primary_pattern, 179 ContentSettingsPattern* secondary_pattern) { 180 if (include_incognito) { 181 // Check incognito-only specific settings. It's essential that the 182 // |RuleIterator| gets out of scope before we get a rule iterator for the 183 // normal mode. 184 scoped_ptr<RuleIterator> incognito_rule_iterator( 185 provider->GetRuleIterator(content_type, resource_identifier, true)); 186 base::Value* value = GetContentSettingValueAndPatterns( 187 incognito_rule_iterator.get(), primary_url, secondary_url, 188 primary_pattern, secondary_pattern); 189 if (value) 190 return value; 191 } 192 // No settings from the incognito; use the normal mode. 193 scoped_ptr<RuleIterator> rule_iterator( 194 provider->GetRuleIterator(content_type, resource_identifier, false)); 195 return GetContentSettingValueAndPatterns( 196 rule_iterator.get(), primary_url, secondary_url, 197 primary_pattern, secondary_pattern); 198 } 199 200 base::Value* GetContentSettingValueAndPatterns( 201 RuleIterator* rule_iterator, 202 const GURL& primary_url, 203 const GURL& secondary_url, 204 ContentSettingsPattern* primary_pattern, 205 ContentSettingsPattern* secondary_pattern) { 206 while (rule_iterator->HasNext()) { 207 const Rule& rule = rule_iterator->Next(); 208 if (rule.primary_pattern.Matches(primary_url) && 209 rule.secondary_pattern.Matches(secondary_url)) { 210 if (primary_pattern) 211 *primary_pattern = rule.primary_pattern; 212 if (secondary_pattern) 213 *secondary_pattern = rule.secondary_pattern; 214 return rule.value.get()->DeepCopy(); 215 } 216 } 217 return NULL; 218 } 219 220 base::Value* GetContentSettingValue(const ProviderInterface* provider, 221 const GURL& primary_url, 222 const GURL& secondary_url, 223 ContentSettingsType content_type, 224 const std::string& resource_identifier, 225 bool include_incognito) { 226 return GetContentSettingValueAndPatterns(provider, primary_url, secondary_url, 227 content_type, resource_identifier, 228 include_incognito, NULL, NULL); 229 } 230 231 ContentSetting GetContentSetting(const ProviderInterface* provider, 232 const GURL& primary_url, 233 const GURL& secondary_url, 234 ContentSettingsType content_type, 235 const std::string& resource_identifier, 236 bool include_incognito) { 237 scoped_ptr<base::Value> value( 238 GetContentSettingValue(provider, primary_url, secondary_url, 239 content_type, resource_identifier, 240 include_incognito)); 241 return ValueToContentSetting(value.get()); 242 } 243 244 void GetRendererContentSettingRules(const HostContentSettingsMap* map, 245 RendererContentSettingRules* rules) { 246 map->GetSettingsForOneType( 247 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), &(rules->image_rules)); 248 map->GetSettingsForOneType( 249 CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string(), &(rules->script_rules)); 250 } 251 252 } // namespace content_settings 253