| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" | 5 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/memory/ptr_util.h" |
| 14 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 17 #include "base/values.h" | 18 #include "base/values.h" |
| 18 #include "chrome/grit/generated_resources.h" | 19 #include "chrome/grit/generated_resources.h" |
| 19 #include "content/public/common/url_constants.h" | 20 #include "content/public/common/url_constants.h" |
| 20 #include "extensions/common/error_utils.h" | 21 #include "extensions/common/error_utils.h" |
| 21 #include "extensions/common/extension.h" | 22 #include "extensions/common/extension.h" |
| 22 #include "extensions/common/extension_resource.h" | 23 #include "extensions/common/extension_resource.h" |
| 23 #include "extensions/common/host_id.h" | 24 #include "extensions/common/host_id.h" |
| 24 #include "extensions/common/manifest_constants.h" | 25 #include "extensions/common/manifest_constants.h" |
| 25 #include "extensions/common/manifest_handlers/permissions_parser.h" | 26 #include "extensions/common/manifest_handlers/permissions_parser.h" |
| 26 #include "extensions/common/permissions/permissions_data.h" | 27 #include "extensions/common/permissions/permissions_data.h" |
| 27 #include "extensions/common/url_pattern.h" | 28 #include "extensions/common/url_pattern.h" |
| 28 #include "extensions/common/url_pattern_set.h" | 29 #include "extensions/common/url_pattern_set.h" |
| 29 #include "ui/base/l10n/l10n_util.h" | 30 #include "ui/base/l10n/l10n_util.h" |
| 30 #include "url/gurl.h" | 31 #include "url/gurl.h" |
| 31 | 32 |
| 32 namespace extensions { | 33 namespace extensions { |
| 33 | 34 |
| 34 namespace keys = extensions::manifest_keys; | 35 namespace keys = extensions::manifest_keys; |
| 35 namespace values = manifest_values; | 36 namespace values = manifest_values; |
| 36 namespace errors = manifest_errors; | 37 namespace errors = manifest_errors; |
| 37 | 38 |
| 38 namespace { | 39 namespace { |
| 39 | 40 |
| 40 // Helper method that loads either the include_globs or exclude_globs list | 41 // Helper method that loads either the include_globs or exclude_globs list |
| 41 // from an entry in the content_script lists of the manifest. | 42 // from an entry in the content_script lists of the manifest. |
| 42 bool LoadGlobsHelper(const base::DictionaryValue* content_script, | 43 bool LoadGlobsHelper( |
| 43 int content_script_index, | 44 const base::DictionaryValue* content_script, |
| 44 const char* globs_property_name, | 45 int content_script_index, |
| 45 base::string16* error, | 46 const char* globs_property_name, |
| 46 void(UserScript::*add_method)(const std::string& glob), | 47 base::string16* error, |
| 47 UserScript* instance) { | 48 void (UserScriptInfo::*add_method)(const std::string& glob), |
| 49 ScriptMetadata* instance) { |
| 48 if (!content_script->HasKey(globs_property_name)) | 50 if (!content_script->HasKey(globs_property_name)) |
| 49 return true; // they are optional | 51 return true; // they are optional |
| 50 | 52 |
| 51 const base::ListValue* list = NULL; | 53 const base::ListValue* list = NULL; |
| 52 if (!content_script->GetList(globs_property_name, &list)) { | 54 if (!content_script->GetList(globs_property_name, &list)) { |
| 53 *error = ErrorUtils::FormatErrorMessageUTF16( | 55 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 54 errors::kInvalidGlobList, | 56 errors::kInvalidGlobList, |
| 55 base::IntToString(content_script_index), | 57 base::IntToString(content_script_index), |
| 56 globs_property_name); | 58 globs_property_name); |
| 57 return false; | 59 return false; |
| 58 } | 60 } |
| 59 | 61 |
| 60 for (size_t i = 0; i < list->GetSize(); ++i) { | 62 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 61 std::string glob; | 63 std::string glob; |
| 62 if (!list->GetString(i, &glob)) { | 64 if (!list->GetString(i, &glob)) { |
| 63 *error = ErrorUtils::FormatErrorMessageUTF16( | 65 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 64 errors::kInvalidGlob, base::IntToString(content_script_index), | 66 errors::kInvalidGlob, base::IntToString(content_script_index), |
| 65 globs_property_name, base::SizeTToString(i)); | 67 globs_property_name, base::SizeTToString(i)); |
| 66 return false; | 68 return false; |
| 67 } | 69 } |
| 68 | 70 |
| 69 (instance->*add_method)(glob); | 71 (instance->*add_method)(glob); |
| 70 } | 72 } |
| 71 | 73 |
| 72 return true; | 74 return true; |
| 73 } | 75 } |
| 74 | 76 |
| 75 // Helper method that loads a UserScript object from a dictionary in the | 77 // Helper method that loads a UserScript object from a dictionary in the |
| 76 // content_script list of the manifest. | 78 // content_script list of the manifest. |
| 77 bool LoadUserScriptFromDictionary(const base::DictionaryValue* content_script, | 79 std::unique_ptr<ScriptMetadata> LoadUserScriptFromDictionary( |
| 78 int definition_index, | 80 const base::DictionaryValue* content_script, |
| 79 Extension* extension, | 81 int definition_index, |
| 80 base::string16* error, | 82 Extension* extension, |
| 81 UserScript* result) { | 83 base::string16* error) { |
| 84 std::unique_ptr<ScriptMetadata> result(new ScriptMetadata); |
| 82 // run_at | 85 // run_at |
| 83 if (content_script->HasKey(keys::kRunAt)) { | 86 if (content_script->HasKey(keys::kRunAt)) { |
| 84 std::string run_location; | 87 std::string run_location; |
| 85 if (!content_script->GetString(keys::kRunAt, &run_location)) { | 88 if (!content_script->GetString(keys::kRunAt, &run_location)) { |
| 86 *error = ErrorUtils::FormatErrorMessageUTF16( | 89 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 87 errors::kInvalidRunAt, | 90 errors::kInvalidRunAt, |
| 88 base::IntToString(definition_index)); | 91 base::IntToString(definition_index)); |
| 89 return false; | 92 return std::unique_ptr<ScriptMetadata>(); |
| 90 } | 93 } |
| 91 | 94 |
| 92 if (run_location == values::kRunAtDocumentStart) { | 95 if (run_location == values::kRunAtDocumentStart) { |
| 93 result->set_run_location(UserScript::DOCUMENT_START); | 96 result->set_run_location(UserScript::DOCUMENT_START); |
| 94 } else if (run_location == values::kRunAtDocumentEnd) { | 97 } else if (run_location == values::kRunAtDocumentEnd) { |
| 95 result->set_run_location(UserScript::DOCUMENT_END); | 98 result->set_run_location(UserScript::DOCUMENT_END); |
| 96 } else if (run_location == values::kRunAtDocumentIdle) { | 99 } else if (run_location == values::kRunAtDocumentIdle) { |
| 97 result->set_run_location(UserScript::DOCUMENT_IDLE); | 100 result->set_run_location(UserScript::DOCUMENT_IDLE); |
| 98 } else { | 101 } else { |
| 99 *error = ErrorUtils::FormatErrorMessageUTF16( | 102 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 100 errors::kInvalidRunAt, | 103 errors::kInvalidRunAt, |
| 101 base::IntToString(definition_index)); | 104 base::IntToString(definition_index)); |
| 102 return false; | 105 return std::unique_ptr<ScriptMetadata>(); |
| 103 } | 106 } |
| 104 } | 107 } |
| 105 | 108 |
| 106 // all frames | 109 // all frames |
| 107 if (content_script->HasKey(keys::kAllFrames)) { | 110 if (content_script->HasKey(keys::kAllFrames)) { |
| 108 bool all_frames = false; | 111 bool all_frames = false; |
| 109 if (!content_script->GetBoolean(keys::kAllFrames, &all_frames)) { | 112 if (!content_script->GetBoolean(keys::kAllFrames, &all_frames)) { |
| 110 *error = ErrorUtils::FormatErrorMessageUTF16( | 113 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 111 errors::kInvalidAllFrames, base::IntToString(definition_index)); | 114 errors::kInvalidAllFrames, base::IntToString(definition_index)); |
| 112 return false; | 115 return std::unique_ptr<ScriptMetadata>(); |
| 113 } | 116 } |
| 114 result->set_match_all_frames(all_frames); | 117 result->set_match_all_frames(all_frames); |
| 115 } | 118 } |
| 116 | 119 |
| 117 // match about blank | 120 // match about blank |
| 118 if (content_script->HasKey(keys::kMatchAboutBlank)) { | 121 if (content_script->HasKey(keys::kMatchAboutBlank)) { |
| 119 bool match_about_blank = false; | 122 bool match_about_blank = false; |
| 120 if (!content_script->GetBoolean(keys::kMatchAboutBlank, | 123 if (!content_script->GetBoolean(keys::kMatchAboutBlank, |
| 121 &match_about_blank)) { | 124 &match_about_blank)) { |
| 122 *error = ErrorUtils::FormatErrorMessageUTF16( | 125 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 123 errors::kInvalidMatchAboutBlank, base::IntToString(definition_index)); | 126 errors::kInvalidMatchAboutBlank, base::IntToString(definition_index)); |
| 124 return false; | 127 return std::unique_ptr<ScriptMetadata>(); |
| 125 } | 128 } |
| 126 result->set_match_about_blank(match_about_blank); | 129 result->set_match_about_blank(match_about_blank); |
| 127 } | 130 } |
| 128 | 131 |
| 129 // matches (required) | 132 // matches (required) |
| 130 const base::ListValue* matches = NULL; | 133 const base::ListValue* matches = NULL; |
| 131 if (!content_script->GetList(keys::kMatches, &matches)) { | 134 if (!content_script->GetList(keys::kMatches, &matches)) { |
| 132 *error = ErrorUtils::FormatErrorMessageUTF16( | 135 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 133 errors::kInvalidMatches, | 136 errors::kInvalidMatches, |
| 134 base::IntToString(definition_index)); | 137 base::IntToString(definition_index)); |
| 135 return false; | 138 return std::unique_ptr<ScriptMetadata>(); |
| 136 } | 139 } |
| 137 | 140 |
| 138 if (matches->GetSize() == 0) { | 141 if (matches->GetSize() == 0) { |
| 139 *error = ErrorUtils::FormatErrorMessageUTF16( | 142 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 140 errors::kInvalidMatchCount, | 143 errors::kInvalidMatchCount, |
| 141 base::IntToString(definition_index)); | 144 base::IntToString(definition_index)); |
| 142 return false; | 145 return std::unique_ptr<ScriptMetadata>(); |
| 143 } | 146 } |
| 144 for (size_t j = 0; j < matches->GetSize(); ++j) { | 147 for (size_t j = 0; j < matches->GetSize(); ++j) { |
| 145 std::string match_str; | 148 std::string match_str; |
| 146 if (!matches->GetString(j, &match_str)) { | 149 if (!matches->GetString(j, &match_str)) { |
| 147 *error = ErrorUtils::FormatErrorMessageUTF16( | 150 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 148 errors::kInvalidMatch, base::IntToString(definition_index), | 151 errors::kInvalidMatch, base::IntToString(definition_index), |
| 149 base::SizeTToString(j), errors::kExpectString); | 152 base::SizeTToString(j), errors::kExpectString); |
| 150 return false; | 153 return std::unique_ptr<ScriptMetadata>(); |
| 151 } | 154 } |
| 152 | 155 |
| 153 URLPattern pattern(UserScript::ValidUserScriptSchemes( | 156 URLPattern pattern(UserScript::ValidUserScriptSchemes( |
| 154 PermissionsData::CanExecuteScriptEverywhere(extension))); | 157 PermissionsData::CanExecuteScriptEverywhere(extension))); |
| 155 | 158 |
| 156 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | 159 URLPattern::ParseResult parse_result = pattern.Parse(match_str); |
| 157 if (parse_result != URLPattern::PARSE_SUCCESS) { | 160 if (parse_result != URLPattern::PARSE_SUCCESS) { |
| 158 *error = ErrorUtils::FormatErrorMessageUTF16( | 161 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 159 errors::kInvalidMatch, base::IntToString(definition_index), | 162 errors::kInvalidMatch, base::IntToString(definition_index), |
| 160 base::SizeTToString(j), | 163 base::SizeTToString(j), |
| 161 URLPattern::GetParseResultString(parse_result)); | 164 URLPattern::GetParseResultString(parse_result)); |
| 162 return false; | 165 return std::unique_ptr<ScriptMetadata>(); |
| 163 } | 166 } |
| 164 | 167 |
| 165 // TODO(aboxhall): check for webstore | 168 // TODO(aboxhall): check for webstore |
| 166 if (!PermissionsData::CanExecuteScriptEverywhere(extension) && | 169 if (!PermissionsData::CanExecuteScriptEverywhere(extension) && |
| 167 pattern.scheme() != content::kChromeUIScheme) { | 170 pattern.scheme() != content::kChromeUIScheme) { |
| 168 // Exclude SCHEME_CHROMEUI unless it's been explicitly requested. | 171 // Exclude SCHEME_CHROMEUI unless it's been explicitly requested. |
| 169 // If the --extensions-on-chrome-urls flag has not been passed, requesting | 172 // If the --extensions-on-chrome-urls flag has not been passed, requesting |
| 170 // a chrome:// url will cause a parse failure above, so there's no need to | 173 // a chrome:// url will cause a parse failure above, so there's no need to |
| 171 // check the flag here. | 174 // check the flag here. |
| 172 pattern.SetValidSchemes( | 175 pattern.SetValidSchemes( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 185 result->add_url_pattern(pattern); | 188 result->add_url_pattern(pattern); |
| 186 } | 189 } |
| 187 | 190 |
| 188 // exclude_matches | 191 // exclude_matches |
| 189 if (content_script->HasKey(keys::kExcludeMatches)) { // optional | 192 if (content_script->HasKey(keys::kExcludeMatches)) { // optional |
| 190 const base::ListValue* exclude_matches = NULL; | 193 const base::ListValue* exclude_matches = NULL; |
| 191 if (!content_script->GetList(keys::kExcludeMatches, &exclude_matches)) { | 194 if (!content_script->GetList(keys::kExcludeMatches, &exclude_matches)) { |
| 192 *error = ErrorUtils::FormatErrorMessageUTF16( | 195 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 193 errors::kInvalidExcludeMatches, | 196 errors::kInvalidExcludeMatches, |
| 194 base::IntToString(definition_index)); | 197 base::IntToString(definition_index)); |
| 195 return false; | 198 return std::unique_ptr<ScriptMetadata>(); |
| 196 } | 199 } |
| 197 | 200 |
| 198 for (size_t j = 0; j < exclude_matches->GetSize(); ++j) { | 201 for (size_t j = 0; j < exclude_matches->GetSize(); ++j) { |
| 199 std::string match_str; | 202 std::string match_str; |
| 200 if (!exclude_matches->GetString(j, &match_str)) { | 203 if (!exclude_matches->GetString(j, &match_str)) { |
| 201 *error = ErrorUtils::FormatErrorMessageUTF16( | 204 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 202 errors::kInvalidExcludeMatch, base::IntToString(definition_index), | 205 errors::kInvalidExcludeMatch, base::IntToString(definition_index), |
| 203 base::SizeTToString(j), errors::kExpectString); | 206 base::SizeTToString(j), errors::kExpectString); |
| 204 return false; | 207 return std::unique_ptr<ScriptMetadata>(); |
| 205 } | 208 } |
| 206 | 209 |
| 207 int valid_schemes = UserScript::ValidUserScriptSchemes( | 210 int valid_schemes = UserScript::ValidUserScriptSchemes( |
| 208 PermissionsData::CanExecuteScriptEverywhere(extension)); | 211 PermissionsData::CanExecuteScriptEverywhere(extension)); |
| 209 URLPattern pattern(valid_schemes); | 212 URLPattern pattern(valid_schemes); |
| 210 | 213 |
| 211 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | 214 URLPattern::ParseResult parse_result = pattern.Parse(match_str); |
| 212 if (parse_result != URLPattern::PARSE_SUCCESS) { | 215 if (parse_result != URLPattern::PARSE_SUCCESS) { |
| 213 *error = ErrorUtils::FormatErrorMessageUTF16( | 216 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 214 errors::kInvalidExcludeMatch, base::IntToString(definition_index), | 217 errors::kInvalidExcludeMatch, base::IntToString(definition_index), |
| 215 base::SizeTToString(j), | 218 base::SizeTToString(j), |
| 216 URLPattern::GetParseResultString(parse_result)); | 219 URLPattern::GetParseResultString(parse_result)); |
| 217 return false; | 220 return std::unique_ptr<ScriptMetadata>(); |
| 218 } | 221 } |
| 219 | 222 |
| 220 result->add_exclude_url_pattern(pattern); | 223 result->add_exclude_url_pattern(pattern); |
| 221 } | 224 } |
| 222 } | 225 } |
| 223 | 226 |
| 224 // include/exclude globs (mostly for Greasemonkey compatibility) | 227 // include/exclude globs (mostly for Greasemonkey compatibility) |
| 225 if (!LoadGlobsHelper(content_script, definition_index, keys::kIncludeGlobs, | 228 if (!LoadGlobsHelper(content_script, definition_index, keys::kIncludeGlobs, |
| 226 error, &UserScript::add_glob, result)) { | 229 error, &UserScriptInfo::add_glob, result.get())) { |
| 227 return false; | 230 return std::unique_ptr<ScriptMetadata>(); |
| 228 } | 231 } |
| 229 | 232 |
| 230 if (!LoadGlobsHelper(content_script, definition_index, keys::kExcludeGlobs, | 233 if (!LoadGlobsHelper(content_script, definition_index, keys::kExcludeGlobs, |
| 231 error, &UserScript::add_exclude_glob, result)) { | 234 error, &UserScriptInfo::add_exclude_glob, |
| 232 return false; | 235 result.get())) { |
| 236 return std::unique_ptr<ScriptMetadata>(); |
| 233 } | 237 } |
| 234 | 238 |
| 235 // js and css keys | 239 // js and css keys |
| 236 const base::ListValue* js = NULL; | 240 const base::ListValue* js = NULL; |
| 237 if (content_script->HasKey(keys::kJs) && | 241 if (content_script->HasKey(keys::kJs) && |
| 238 !content_script->GetList(keys::kJs, &js)) { | 242 !content_script->GetList(keys::kJs, &js)) { |
| 239 *error = ErrorUtils::FormatErrorMessageUTF16( | 243 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 240 errors::kInvalidJsList, | 244 errors::kInvalidJsList, |
| 241 base::IntToString(definition_index)); | 245 base::IntToString(definition_index)); |
| 242 return false; | 246 return std::unique_ptr<ScriptMetadata>(); |
| 243 } | 247 } |
| 244 | 248 |
| 245 const base::ListValue* css = NULL; | 249 const base::ListValue* css = NULL; |
| 246 if (content_script->HasKey(keys::kCss) && | 250 if (content_script->HasKey(keys::kCss) && |
| 247 !content_script->GetList(keys::kCss, &css)) { | 251 !content_script->GetList(keys::kCss, &css)) { |
| 248 *error = ErrorUtils:: | 252 *error = ErrorUtils:: |
| 249 FormatErrorMessageUTF16(errors::kInvalidCssList, | 253 FormatErrorMessageUTF16(errors::kInvalidCssList, |
| 250 base::IntToString(definition_index)); | 254 base::IntToString(definition_index)); |
| 251 return false; | 255 return std::unique_ptr<ScriptMetadata>(); |
| 252 } | 256 } |
| 253 | 257 |
| 254 // The manifest needs to have at least one js or css user script definition. | 258 // The manifest needs to have at least one js or css user script definition. |
| 255 if (((js ? js->GetSize() : 0) + (css ? css->GetSize() : 0)) == 0) { | 259 if (((js ? js->GetSize() : 0) + (css ? css->GetSize() : 0)) == 0) { |
| 256 *error = ErrorUtils::FormatErrorMessageUTF16( | 260 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 257 errors::kMissingFile, | 261 errors::kMissingFile, |
| 258 base::IntToString(definition_index)); | 262 base::IntToString(definition_index)); |
| 259 return false; | 263 return std::unique_ptr<ScriptMetadata>(); |
| 260 } | 264 } |
| 261 | 265 |
| 262 if (js) { | 266 if (js) { |
| 267 result->js_scripts().reserve(js->GetSize()); |
| 263 for (size_t script_index = 0; script_index < js->GetSize(); | 268 for (size_t script_index = 0; script_index < js->GetSize(); |
| 264 ++script_index) { | 269 ++script_index) { |
| 265 const base::Value* value; | 270 const base::Value* value; |
| 266 std::string relative; | 271 std::string relative; |
| 267 if (!js->Get(script_index, &value) || !value->GetAsString(&relative)) { | 272 if (!js->Get(script_index, &value) || !value->GetAsString(&relative)) { |
| 268 *error = ErrorUtils::FormatErrorMessageUTF16( | 273 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 269 errors::kInvalidJs, base::IntToString(definition_index), | 274 errors::kInvalidJs, base::IntToString(definition_index), |
| 270 base::SizeTToString(script_index)); | 275 base::SizeTToString(script_index)); |
| 271 return false; | 276 return std::unique_ptr<ScriptMetadata>(); |
| 272 } | 277 } |
| 273 GURL url = extension->GetResourceURL(relative); | 278 GURL url = extension->GetResourceURL(relative); |
| 274 ExtensionResource resource = extension->GetResource(relative); | 279 ExtensionResource resource = extension->GetResource(relative); |
| 275 result->js_scripts().push_back(UserScript::File( | 280 result->js_scripts().push_back(base::WrapUnique(new UserScriptFileInfo( |
| 276 resource.extension_root(), resource.relative_path(), url)); | 281 resource.extension_root(), resource.relative_path(), url))); |
| 277 } | 282 } |
| 278 } | 283 } |
| 279 | 284 |
| 280 if (css) { | 285 if (css) { |
| 286 result->css_scripts().reserve(css->GetSize()); |
| 281 for (size_t script_index = 0; script_index < css->GetSize(); | 287 for (size_t script_index = 0; script_index < css->GetSize(); |
| 282 ++script_index) { | 288 ++script_index) { |
| 283 const base::Value* value; | 289 const base::Value* value; |
| 284 std::string relative; | 290 std::string relative; |
| 285 if (!css->Get(script_index, &value) || !value->GetAsString(&relative)) { | 291 if (!css->Get(script_index, &value) || !value->GetAsString(&relative)) { |
| 286 *error = ErrorUtils::FormatErrorMessageUTF16( | 292 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 287 errors::kInvalidCss, base::IntToString(definition_index), | 293 errors::kInvalidCss, base::IntToString(definition_index), |
| 288 base::SizeTToString(script_index)); | 294 base::SizeTToString(script_index)); |
| 289 return false; | 295 return std::unique_ptr<ScriptMetadata>(); |
| 290 } | 296 } |
| 291 GURL url = extension->GetResourceURL(relative); | 297 GURL url = extension->GetResourceURL(relative); |
| 292 ExtensionResource resource = extension->GetResource(relative); | 298 ExtensionResource resource = extension->GetResource(relative); |
| 293 result->css_scripts().push_back(UserScript::File( | 299 result->css_scripts().push_back(base::WrapUnique(new UserScriptFileInfo( |
| 294 resource.extension_root(), resource.relative_path(), url)); | 300 resource.extension_root(), resource.relative_path(), url))); |
| 295 } | 301 } |
| 296 } | 302 } |
| 297 | 303 return result; |
| 298 return true; | |
| 299 } | 304 } |
| 300 | 305 |
| 301 // Returns false and sets the error if script file can't be loaded, | 306 // Returns false and sets the error if script file can't be loaded, |
| 302 // or if it's not UTF-8 encoded. | 307 // or if it's not UTF-8 encoded. |
| 303 static bool IsScriptValid(const base::FilePath& path, | 308 static bool IsScriptValid(const base::FilePath& path, |
| 304 const base::FilePath& relative_path, | 309 const base::FilePath& relative_path, |
| 305 int message_id, | 310 int message_id, |
| 306 std::string* error) { | 311 std::string* error) { |
| 307 std::string content; | 312 std::string content; |
| 308 if (!base::PathExists(path) || | 313 if (!base::PathExists(path) || |
| 309 !base::ReadFileToString(path, &content)) { | 314 !base::ReadFileToString(path, &content)) { |
| 310 *error = l10n_util::GetStringFUTF8( | 315 *error = l10n_util::GetStringFUTF8( |
| 311 message_id, | 316 message_id, |
| 312 relative_path.LossyDisplayName()); | 317 relative_path.LossyDisplayName()); |
| 313 return false; | 318 return false; |
| 314 } | 319 } |
| 315 | 320 |
| 316 if (!base::IsStringUTF8(content)) { | 321 if (!base::IsStringUTF8(content)) { |
| 317 *error = l10n_util::GetStringFUTF8( | 322 *error = l10n_util::GetStringFUTF8( |
| 318 IDS_EXTENSION_BAD_FILE_ENCODING, | 323 IDS_EXTENSION_BAD_FILE_ENCODING, |
| 319 relative_path.LossyDisplayName()); | 324 relative_path.LossyDisplayName()); |
| 320 return false; | 325 return false; |
| 321 } | 326 } |
| 322 | 327 |
| 323 return true; | 328 return true; |
| 324 } | 329 } |
| 325 | 330 |
| 326 struct EmptyUserScriptList { | 331 struct EmptyScriptMetadatalist { |
| 327 UserScriptList user_script_list; | 332 ScriptMetadataList user_script_list; |
| 328 }; | 333 }; |
| 329 | 334 |
| 330 static base::LazyInstance<EmptyUserScriptList> g_empty_script_list = | 335 static base::LazyInstance<EmptyScriptMetadatalist> g_empty_script_list = |
| 331 LAZY_INSTANCE_INITIALIZER; | 336 LAZY_INSTANCE_INITIALIZER; |
| 332 | 337 |
| 333 } // namespace | 338 } // namespace |
| 334 | 339 |
| 335 ContentScriptsInfo::ContentScriptsInfo() { | 340 ContentScriptsInfo::ContentScriptsInfo() { |
| 336 } | 341 } |
| 337 | 342 |
| 338 ContentScriptsInfo::~ContentScriptsInfo() { | 343 ContentScriptsInfo::~ContentScriptsInfo() { |
| 339 } | 344 } |
| 340 | 345 |
| 341 // static | 346 // static |
| 342 const UserScriptList& ContentScriptsInfo::GetContentScripts( | 347 const ScriptMetadataList& ContentScriptsInfo::GetContentScripts( |
| 343 const Extension* extension) { | 348 const Extension* extension) { |
| 344 ContentScriptsInfo* info = static_cast<ContentScriptsInfo*>( | 349 ContentScriptsInfo* info = static_cast<ContentScriptsInfo*>( |
| 345 extension->GetManifestData(keys::kContentScripts)); | 350 extension->GetManifestData(keys::kContentScripts)); |
| 346 return info ? info->content_scripts | 351 return info ? info->content_scripts |
| 347 : g_empty_script_list.Get().user_script_list; | 352 : g_empty_script_list.Get().user_script_list; |
| 348 } | 353 } |
| 349 | 354 |
| 350 // static | 355 // static |
| 351 bool ContentScriptsInfo::ExtensionHasScriptAtURL(const Extension* extension, | 356 bool ContentScriptsInfo::ExtensionHasScriptAtURL(const Extension* extension, |
| 352 const GURL& url) { | 357 const GURL& url) { |
| 353 const UserScriptList& content_scripts = GetContentScripts(extension); | 358 const ScriptMetadataList& content_scripts = GetContentScripts(extension); |
| 354 for (UserScriptList::const_iterator iter = content_scripts.begin(); | 359 for (const std::unique_ptr<ScriptMetadata>& meta : content_scripts) { |
| 355 iter != content_scripts.end(); ++iter) { | 360 if (meta->MatchesURL(url)) |
| 356 if (iter->MatchesURL(url)) | |
| 357 return true; | 361 return true; |
| 358 } | 362 } |
| 359 return false; | 363 return false; |
| 360 } | 364 } |
| 361 | 365 |
| 362 // static | 366 // static |
| 363 URLPatternSet ContentScriptsInfo::GetScriptableHosts( | 367 URLPatternSet ContentScriptsInfo::GetScriptableHosts( |
| 364 const Extension* extension) { | 368 const Extension* extension) { |
| 365 const UserScriptList& content_scripts = GetContentScripts(extension); | 369 const ScriptMetadataList& content_scripts = GetContentScripts(extension); |
| 366 URLPatternSet scriptable_hosts; | 370 URLPatternSet scriptable_hosts; |
| 367 for (UserScriptList::const_iterator content_script = | 371 for (const std::unique_ptr<ScriptMetadata>& meta : content_scripts) { |
| 368 content_scripts.begin(); | 372 URLPatternSet::const_iterator pattern = meta->url_patterns().begin(); |
| 369 content_script != content_scripts.end(); | 373 for (; pattern != meta->url_patterns().end(); ++pattern) |
| 370 ++content_script) { | |
| 371 URLPatternSet::const_iterator pattern = | |
| 372 content_script->url_patterns().begin(); | |
| 373 for (; pattern != content_script->url_patterns().end(); ++pattern) | |
| 374 scriptable_hosts.AddPattern(*pattern); | 374 scriptable_hosts.AddPattern(*pattern); |
| 375 } | 375 } |
| 376 return scriptable_hosts; | 376 return scriptable_hosts; |
| 377 } | 377 } |
| 378 | 378 |
| 379 ContentScriptsHandler::ContentScriptsHandler() { | 379 ContentScriptsHandler::ContentScriptsHandler() { |
| 380 } | 380 } |
| 381 | 381 |
| 382 ContentScriptsHandler::~ContentScriptsHandler() { | 382 ContentScriptsHandler::~ContentScriptsHandler() { |
| 383 } | 383 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 399 } | 399 } |
| 400 | 400 |
| 401 for (size_t i = 0; i < scripts_list->GetSize(); ++i) { | 401 for (size_t i = 0; i < scripts_list->GetSize(); ++i) { |
| 402 const base::DictionaryValue* script_dict = NULL; | 402 const base::DictionaryValue* script_dict = NULL; |
| 403 if (!scripts_list->GetDictionary(i, &script_dict)) { | 403 if (!scripts_list->GetDictionary(i, &script_dict)) { |
| 404 *error = ErrorUtils::FormatErrorMessageUTF16( | 404 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 405 errors::kInvalidContentScript, base::SizeTToString(i)); | 405 errors::kInvalidContentScript, base::SizeTToString(i)); |
| 406 return false; | 406 return false; |
| 407 } | 407 } |
| 408 | 408 |
| 409 UserScript user_script; | 409 std::unique_ptr<ScriptMetadata> meta = |
| 410 if (!LoadUserScriptFromDictionary(script_dict, | 410 LoadUserScriptFromDictionary(script_dict, i, extension, error); |
| 411 i, | 411 if (!meta.get()) |
| 412 extension, | |
| 413 error, | |
| 414 &user_script)) { | |
| 415 return false; // Failed to parse script context definition. | 412 return false; // Failed to parse script context definition. |
| 413 |
| 414 meta->set_host_id(HostID(HostID::EXTENSIONS, extension->id())); |
| 415 if (extension->converted_from_user_script()) { |
| 416 meta->set_emulate_greasemonkey(true); |
| 417 // Greasemonkey matches all frames. |
| 418 meta->set_match_all_frames(true); |
| 416 } | 419 } |
| 417 | 420 meta->set_id(UserScript::GenerateUserScriptID()); |
| 418 user_script.set_host_id(HostID(HostID::EXTENSIONS, extension->id())); | 421 content_scripts_info->content_scripts.push_back(std::move(meta)); |
| 419 if (extension->converted_from_user_script()) { | |
| 420 user_script.set_emulate_greasemonkey(true); | |
| 421 // Greasemonkey matches all frames. | |
| 422 user_script.set_match_all_frames(true); | |
| 423 } | |
| 424 user_script.set_id(UserScript::GenerateUserScriptID()); | |
| 425 content_scripts_info->content_scripts.push_back(user_script); | |
| 426 } | 422 } |
| 427 extension->SetManifestData(keys::kContentScripts, | 423 extension->SetManifestData(keys::kContentScripts, |
| 428 content_scripts_info.release()); | 424 content_scripts_info.release()); |
| 429 PermissionsParser::SetScriptableHosts( | 425 PermissionsParser::SetScriptableHosts( |
| 430 extension, ContentScriptsInfo::GetScriptableHosts(extension)); | 426 extension, ContentScriptsInfo::GetScriptableHosts(extension)); |
| 431 return true; | 427 return true; |
| 432 } | 428 } |
| 433 | 429 |
| 434 bool ContentScriptsHandler::Validate( | 430 bool ContentScriptsHandler::Validate( |
| 435 const Extension* extension, | 431 const Extension* extension, |
| 436 std::string* error, | 432 std::string* error, |
| 437 std::vector<InstallWarning>* warnings) const { | 433 std::vector<InstallWarning>* warnings) const { |
| 438 // Validate that claimed script resources actually exist, | 434 // Validate that claimed script resources actually exist, |
| 439 // and are UTF-8 encoded. | 435 // and are UTF-8 encoded. |
| 440 ExtensionResource::SymlinkPolicy symlink_policy; | 436 ExtensionResource::SymlinkPolicy symlink_policy; |
| 441 if ((extension->creation_flags() & | 437 if ((extension->creation_flags() & |
| 442 Extension::FOLLOW_SYMLINKS_ANYWHERE) != 0) { | 438 Extension::FOLLOW_SYMLINKS_ANYWHERE) != 0) { |
| 443 symlink_policy = ExtensionResource::FOLLOW_SYMLINKS_ANYWHERE; | 439 symlink_policy = ExtensionResource::FOLLOW_SYMLINKS_ANYWHERE; |
| 444 } else { | 440 } else { |
| 445 symlink_policy = ExtensionResource::SYMLINKS_MUST_RESOLVE_WITHIN_ROOT; | 441 symlink_policy = ExtensionResource::SYMLINKS_MUST_RESOLVE_WITHIN_ROOT; |
| 446 } | 442 } |
| 447 | 443 |
| 448 const UserScriptList& content_scripts = | 444 const ScriptMetadataList& content_scripts = |
| 449 ContentScriptsInfo::GetContentScripts(extension); | 445 ContentScriptsInfo::GetContentScripts(extension); |
| 450 for (size_t i = 0; i < content_scripts.size(); ++i) { | 446 for (const std::unique_ptr<ScriptMetadata>& script : content_scripts) { |
| 451 const UserScript& script = content_scripts[i]; | 447 for (const std::unique_ptr<UserScriptFileInfo>& js_script : |
| 452 | 448 script->js_scripts()) { |
| 453 for (size_t j = 0; j < script.js_scripts().size(); j++) { | |
| 454 const UserScript::File& js_script = script.js_scripts()[j]; | |
| 455 const base::FilePath& path = ExtensionResource::GetFilePath( | 449 const base::FilePath& path = ExtensionResource::GetFilePath( |
| 456 js_script.extension_root(), js_script.relative_path(), | 450 js_script->extension_root(), js_script->relative_path(), |
| 457 symlink_policy); | 451 symlink_policy); |
| 458 if (!IsScriptValid(path, js_script.relative_path(), | 452 if (!IsScriptValid(path, js_script->relative_path(), |
| 459 IDS_EXTENSION_LOAD_JAVASCRIPT_FAILED, error)) | 453 IDS_EXTENSION_LOAD_JAVASCRIPT_FAILED, error)) |
| 460 return false; | 454 return false; |
| 461 } | 455 } |
| 462 | 456 |
| 463 for (size_t j = 0; j < script.css_scripts().size(); j++) { | 457 for (const std::unique_ptr<UserScriptFileInfo>& css_script : |
| 464 const UserScript::File& css_script = script.css_scripts()[j]; | 458 script->css_scripts()) { |
| 465 const base::FilePath& path = ExtensionResource::GetFilePath( | 459 const base::FilePath& path = ExtensionResource::GetFilePath( |
| 466 css_script.extension_root(), css_script.relative_path(), | 460 css_script->extension_root(), css_script->relative_path(), |
| 467 symlink_policy); | 461 symlink_policy); |
| 468 if (!IsScriptValid(path, css_script.relative_path(), | 462 if (!IsScriptValid(path, css_script->relative_path(), |
| 469 IDS_EXTENSION_LOAD_CSS_FAILED, error)) | 463 IDS_EXTENSION_LOAD_CSS_FAILED, error)) |
| 470 return false; | 464 return false; |
| 471 } | 465 } |
| 472 } | 466 } |
| 473 | 467 |
| 474 return true; | 468 return true; |
| 475 } | 469 } |
| 476 | 470 |
| 477 } // namespace extensions | 471 } // namespace extensions |
| OLD | NEW |