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