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 #elif defined(OS_ANDROID) || defined(OS_CHROMEOS) 47 "protected-media-identifier", 48 #endif 49 #if defined(OS_ANDROID) 50 "app-banner", 51 #endif 52 }; 53 COMPILE_ASSERT(arraysize(kTypeNames) == CONTENT_SETTINGS_NUM_TYPES, 54 type_names_incorrect_size); 55 56 const char kPatternSeparator[] = ","; 57 58 } // namespace 59 60 namespace content_settings { 61 62 std::string GetTypeName(ContentSettingsType type) { 63 return std::string(kTypeNames[type]); 64 } 65 66 std::string CreatePatternString( 67 const ContentSettingsPattern& item_pattern, 68 const ContentSettingsPattern& top_level_frame_pattern) { 69 return item_pattern.ToString() 70 + std::string(kPatternSeparator) 71 + top_level_frame_pattern.ToString(); 72 } 73 74 PatternPair ParsePatternString(const std::string& pattern_str) { 75 std::vector<std::string> pattern_str_list; 76 base::SplitString(pattern_str, kPatternSeparator[0], &pattern_str_list); 77 78 // If the |pattern_str| is an empty string then the |pattern_string_list| 79 // contains a single empty string. In this case the empty string will be 80 // removed to signal an invalid |pattern_str|. Invalid pattern strings are 81 // handle by the "if"-statment below. So the order of the if statements here 82 // must be preserved. 83 if (pattern_str_list.size() == 1) { 84 if (pattern_str_list[0].empty()) { 85 pattern_str_list.pop_back(); 86 } else { 87 pattern_str_list.push_back("*"); 88 } 89 } 90 91 if (pattern_str_list.size() > 2 || 92 pattern_str_list.size() == 0) { 93 return PatternPair(ContentSettingsPattern(), 94 ContentSettingsPattern()); 95 } 96 97 PatternPair pattern_pair; 98 pattern_pair.first = 99 ContentSettingsPattern::FromString(pattern_str_list[0]); 100 pattern_pair.second = 101 ContentSettingsPattern::FromString(pattern_str_list[1]); 102 return pattern_pair; 103 } 104 105 ContentSetting ValueToContentSetting(const base::Value* value) { 106 ContentSetting setting = CONTENT_SETTING_DEFAULT; 107 bool valid = ParseContentSettingValue(value, &setting); 108 DCHECK(valid); 109 return setting; 110 } 111 112 bool ParseContentSettingValue(const base::Value* value, 113 ContentSetting* setting) { 114 if (!value) { 115 *setting = CONTENT_SETTING_DEFAULT; 116 return true; 117 } 118 int int_value = -1; 119 if (!value->GetAsInteger(&int_value)) 120 return false; 121 *setting = IntToContentSetting(int_value); 122 return *setting != CONTENT_SETTING_DEFAULT; 123 } 124 125 base::Value* GetContentSettingValueAndPatterns( 126 const ProviderInterface* provider, 127 const GURL& primary_url, 128 const GURL& secondary_url, 129 ContentSettingsType content_type, 130 const std::string& resource_identifier, 131 bool include_incognito, 132 ContentSettingsPattern* primary_pattern, 133 ContentSettingsPattern* secondary_pattern) { 134 if (include_incognito) { 135 // Check incognito-only specific settings. It's essential that the 136 // |RuleIterator| gets out of scope before we get a rule iterator for the 137 // normal mode. 138 scoped_ptr<RuleIterator> incognito_rule_iterator( 139 provider->GetRuleIterator(content_type, resource_identifier, true)); 140 base::Value* value = GetContentSettingValueAndPatterns( 141 incognito_rule_iterator.get(), primary_url, secondary_url, 142 primary_pattern, secondary_pattern); 143 if (value) 144 return value; 145 } 146 // No settings from the incognito; use the normal mode. 147 scoped_ptr<RuleIterator> rule_iterator( 148 provider->GetRuleIterator(content_type, resource_identifier, false)); 149 return GetContentSettingValueAndPatterns( 150 rule_iterator.get(), primary_url, secondary_url, 151 primary_pattern, secondary_pattern); 152 } 153 154 base::Value* GetContentSettingValueAndPatterns( 155 RuleIterator* rule_iterator, 156 const GURL& primary_url, 157 const GURL& secondary_url, 158 ContentSettingsPattern* primary_pattern, 159 ContentSettingsPattern* secondary_pattern) { 160 while (rule_iterator->HasNext()) { 161 const Rule& rule = rule_iterator->Next(); 162 if (rule.primary_pattern.Matches(primary_url) && 163 rule.secondary_pattern.Matches(secondary_url)) { 164 if (primary_pattern) 165 *primary_pattern = rule.primary_pattern; 166 if (secondary_pattern) 167 *secondary_pattern = rule.secondary_pattern; 168 return rule.value.get()->DeepCopy(); 169 } 170 } 171 return NULL; 172 } 173 174 base::Value* GetContentSettingValue(const ProviderInterface* provider, 175 const GURL& primary_url, 176 const GURL& secondary_url, 177 ContentSettingsType content_type, 178 const std::string& resource_identifier, 179 bool include_incognito) { 180 return GetContentSettingValueAndPatterns(provider, primary_url, secondary_url, 181 content_type, resource_identifier, 182 include_incognito, NULL, NULL); 183 } 184 185 ContentSetting GetContentSetting(const ProviderInterface* provider, 186 const GURL& primary_url, 187 const GURL& secondary_url, 188 ContentSettingsType content_type, 189 const std::string& resource_identifier, 190 bool include_incognito) { 191 scoped_ptr<base::Value> value( 192 GetContentSettingValue(provider, primary_url, secondary_url, 193 content_type, resource_identifier, 194 include_incognito)); 195 return ValueToContentSetting(value.get()); 196 } 197 198 void GetRendererContentSettingRules(const HostContentSettingsMap* map, 199 RendererContentSettingRules* rules) { 200 map->GetSettingsForOneType( 201 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), &(rules->image_rules)); 202 map->GetSettingsForOneType( 203 CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string(), &(rules->script_rules)); 204 } 205 206 } // namespace content_settings 207