| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/extension_file_util.h" | 5 #include "chrome/common/extensions/extension_file_util.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 DictionaryValue* images_value = extension->GetThemeImages(); | 154 DictionaryValue* images_value = extension->GetThemeImages(); |
| 155 if (images_value) { | 155 if (images_value) { |
| 156 for (DictionaryValue::key_iterator iter = images_value->begin_keys(); | 156 for (DictionaryValue::key_iterator iter = images_value->begin_keys(); |
| 157 iter != images_value->end_keys(); ++iter) { | 157 iter != images_value->end_keys(); ++iter) { |
| 158 std::string val; | 158 std::string val; |
| 159 if (images_value->GetStringWithoutPathExpansion(*iter, &val)) { | 159 if (images_value->GetStringWithoutPathExpansion(*iter, &val)) { |
| 160 FilePath image_path = extension->path().AppendASCII(val); | 160 FilePath image_path = extension->path().AppendASCII(val); |
| 161 if (!file_util::PathExists(image_path)) { | 161 if (!file_util::PathExists(image_path)) { |
| 162 *error = | 162 *error = |
| 163 l10n_util::GetStringFUTF8(IDS_EXTENSION_INVALID_IMAGE_PATH, | 163 l10n_util::GetStringFUTF8(IDS_EXTENSION_INVALID_IMAGE_PATH, |
| 164 WideToUTF16(image_path.ToWStringHack())); | 164 image_path.LossyDisplayName()); |
| 165 return false; | 165 return false; |
| 166 } | 166 } |
| 167 } | 167 } |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 | 170 |
| 171 // Themes cannot contain other extension types. | 171 // Themes cannot contain other extension types. |
| 172 return true; | 172 return true; |
| 173 } | 173 } |
| 174 | 174 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 196 } | 196 } |
| 197 } | 197 } |
| 198 | 198 |
| 199 // Validate claimed plugin paths. | 199 // Validate claimed plugin paths. |
| 200 for (size_t i = 0; i < extension->plugins().size(); ++i) { | 200 for (size_t i = 0; i < extension->plugins().size(); ++i) { |
| 201 const Extension::PluginInfo& plugin = extension->plugins()[i]; | 201 const Extension::PluginInfo& plugin = extension->plugins()[i]; |
| 202 if (!file_util::PathExists(plugin.path)) { | 202 if (!file_util::PathExists(plugin.path)) { |
| 203 *error = | 203 *error = |
| 204 l10n_util::GetStringFUTF8( | 204 l10n_util::GetStringFUTF8( |
| 205 IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED, | 205 IDS_EXTENSION_LOAD_PLUGIN_PATH_FAILED, |
| 206 WideToUTF16(plugin.path.ToWStringHack())); | 206 plugin.path.LossyDisplayName()); |
| 207 return false; | 207 return false; |
| 208 } | 208 } |
| 209 } | 209 } |
| 210 | 210 |
| 211 // Validate icon location for page actions. | 211 // Validate icon location for page actions. |
| 212 ExtensionAction* page_action = extension->page_action(); | 212 ExtensionAction* page_action = extension->page_action(); |
| 213 if (page_action) { | 213 if (page_action) { |
| 214 std::vector<std::string> icon_paths(*page_action->icon_paths()); | 214 std::vector<std::string> icon_paths(*page_action->icon_paths()); |
| 215 if (!page_action->default_icon_path().empty()) | 215 if (!page_action->default_icon_path().empty()) |
| 216 icon_paths.push_back(page_action->default_icon_path()); | 216 icon_paths.push_back(page_action->default_icon_path()); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 243 | 243 |
| 244 // Validate background page location. | 244 // Validate background page location. |
| 245 if (!extension->background_url().is_empty()) { | 245 if (!extension->background_url().is_empty()) { |
| 246 FilePath page_path = ExtensionURLToRelativeFilePath( | 246 FilePath page_path = ExtensionURLToRelativeFilePath( |
| 247 extension->background_url()); | 247 extension->background_url()); |
| 248 const FilePath path = extension->GetResource(page_path).GetFilePath(); | 248 const FilePath path = extension->GetResource(page_path).GetFilePath(); |
| 249 if (path.empty() || !file_util::PathExists(path)) { | 249 if (path.empty() || !file_util::PathExists(path)) { |
| 250 *error = | 250 *error = |
| 251 l10n_util::GetStringFUTF8( | 251 l10n_util::GetStringFUTF8( |
| 252 IDS_EXTENSION_LOAD_BACKGROUND_PAGE_FAILED, | 252 IDS_EXTENSION_LOAD_BACKGROUND_PAGE_FAILED, |
| 253 WideToUTF16(page_path.ToWStringHack())); | 253 page_path.LossyDisplayName()); |
| 254 return false; | 254 return false; |
| 255 } | 255 } |
| 256 } | 256 } |
| 257 | 257 |
| 258 // Validate path to the options page. Don't check the URL for hosted apps, | 258 // Validate path to the options page. Don't check the URL for hosted apps, |
| 259 // because they are expected to refer to an external URL. | 259 // because they are expected to refer to an external URL. |
| 260 if (!extension->options_url().is_empty() && !extension->is_hosted_app()) { | 260 if (!extension->options_url().is_empty() && !extension->is_hosted_app()) { |
| 261 const FilePath options_path = ExtensionURLToRelativeFilePath( | 261 const FilePath options_path = ExtensionURLToRelativeFilePath( |
| 262 extension->options_url()); | 262 extension->options_url()); |
| 263 const FilePath path = extension->GetResource(options_path).GetFilePath(); | 263 const FilePath path = extension->GetResource(options_path).GetFilePath(); |
| 264 if (path.empty() || !file_util::PathExists(path)) { | 264 if (path.empty() || !file_util::PathExists(path)) { |
| 265 *error = | 265 *error = |
| 266 l10n_util::GetStringFUTF8( | 266 l10n_util::GetStringFUTF8( |
| 267 IDS_EXTENSION_LOAD_OPTIONS_PAGE_FAILED, | 267 IDS_EXTENSION_LOAD_OPTIONS_PAGE_FAILED, |
| 268 WideToUTF16(options_path.ToWStringHack())); | 268 options_path.LossyDisplayName()); |
| 269 return false; | 269 return false; |
| 270 } | 270 } |
| 271 } | 271 } |
| 272 | 272 |
| 273 // Validate sidebar default page location. | 273 // Validate sidebar default page location. |
| 274 ExtensionSidebarDefaults* sidebar_defaults = extension->sidebar_defaults(); | 274 ExtensionSidebarDefaults* sidebar_defaults = extension->sidebar_defaults(); |
| 275 if (sidebar_defaults && sidebar_defaults->default_page().is_valid()) { | 275 if (sidebar_defaults && sidebar_defaults->default_page().is_valid()) { |
| 276 FilePath page_path = ExtensionURLToRelativeFilePath( | 276 FilePath page_path = ExtensionURLToRelativeFilePath( |
| 277 sidebar_defaults->default_page()); | 277 sidebar_defaults->default_page()); |
| 278 const FilePath path = extension->GetResource(page_path).GetFilePath(); | 278 const FilePath path = extension->GetResource(page_path).GetFilePath(); |
| 279 if (path.empty() || !file_util::PathExists(path)) { | 279 if (path.empty() || !file_util::PathExists(path)) { |
| 280 *error = | 280 *error = |
| 281 l10n_util::GetStringFUTF8( | 281 l10n_util::GetStringFUTF8( |
| 282 IDS_EXTENSION_LOAD_SIDEBAR_PAGE_FAILED, | 282 IDS_EXTENSION_LOAD_SIDEBAR_PAGE_FAILED, |
| 283 WideToUTF16(page_path.ToWStringHack())); | 283 page_path.LossyDisplayName()); |
| 284 return false; | 284 return false; |
| 285 } | 285 } |
| 286 } | 286 } |
| 287 | 287 |
| 288 // Validate locale info. | 288 // Validate locale info. |
| 289 if (!ValidateLocaleInfo(*extension, error)) | 289 if (!ValidateLocaleInfo(*extension, error)) |
| 290 return false; | 290 return false; |
| 291 | 291 |
| 292 // Check children of extension root to see if any of them start with _ and is | 292 // Check children of extension root to see if any of them start with _ and is |
| 293 // not on the reserved list. | 293 // not on the reserved list. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 305 if (!file_util::DirectoryExists(install_directory)) | 305 if (!file_util::DirectoryExists(install_directory)) |
| 306 return; | 306 return; |
| 307 | 307 |
| 308 VLOG(1) << "Garbage collecting extensions..."; | 308 VLOG(1) << "Garbage collecting extensions..."; |
| 309 file_util::FileEnumerator enumerator(install_directory, | 309 file_util::FileEnumerator enumerator(install_directory, |
| 310 false, // Not recursive. | 310 false, // Not recursive. |
| 311 file_util::FileEnumerator::DIRECTORIES); | 311 file_util::FileEnumerator::DIRECTORIES); |
| 312 FilePath extension_path; | 312 FilePath extension_path; |
| 313 for (extension_path = enumerator.Next(); !extension_path.value().empty(); | 313 for (extension_path = enumerator.Next(); !extension_path.value().empty(); |
| 314 extension_path = enumerator.Next()) { | 314 extension_path = enumerator.Next()) { |
| 315 std::string extension_id = WideToASCII( | 315 std::string extension_id; |
| 316 extension_path.BaseName().ToWStringHack()); | 316 |
| 317 FilePath basename = extension_path.BaseName(); |
| 318 if (IsStringASCII(basename.value())) { |
| 319 extension_id = UTF16ToASCII(basename.LossyDisplayName()); |
| 320 if (!Extension::IdIsValid(extension_id)) |
| 321 extension_id.clear(); |
| 322 } |
| 317 | 323 |
| 318 // Delete directories that aren't valid IDs. | 324 // Delete directories that aren't valid IDs. |
| 319 if (!Extension::IdIsValid(extension_id)) { | 325 if (extension_id.empty()) { |
| 320 LOG(WARNING) << "Invalid extension ID encountered in extensions " | 326 LOG(WARNING) << "Invalid extension ID encountered in extensions " |
| 321 "directory: " << extension_id; | 327 "directory: " << basename.value(); |
| 322 VLOG(1) << "Deleting invalid extension directory " | 328 VLOG(1) << "Deleting invalid extension directory " |
| 323 << WideToASCII(extension_path.ToWStringHack()) << "."; | 329 << extension_path.value() << "."; |
| 324 file_util::Delete(extension_path, true); // Recursive. | 330 file_util::Delete(extension_path, true); // Recursive. |
| 325 continue; | 331 continue; |
| 326 } | 332 } |
| 327 | 333 |
| 328 std::map<std::string, FilePath>::const_iterator iter = | 334 std::map<std::string, FilePath>::const_iterator iter = |
| 329 extension_paths.find(extension_id); | 335 extension_paths.find(extension_id); |
| 330 | 336 |
| 331 // If there is no entry in the prefs file, just delete the directory and | 337 // If there is no entry in the prefs file, just delete the directory and |
| 332 // move on. This can legitimately happen when an uninstall does not | 338 // move on. This can legitimately happen when an uninstall does not |
| 333 // complete, for example, when a plugin is in use at uninstall time. | 339 // complete, for example, when a plugin is in use at uninstall time. |
| 334 if (iter == extension_paths.end()) { | 340 if (iter == extension_paths.end()) { |
| 335 VLOG(1) << "Deleting unreferenced install for directory " | 341 VLOG(1) << "Deleting unreferenced install for directory " |
| 336 << WideToASCII(extension_path.ToWStringHack()) << "."; | 342 << extension_path.LossyDisplayName() << "."; |
| 337 file_util::Delete(extension_path, true); // Recursive. | 343 file_util::Delete(extension_path, true); // Recursive. |
| 338 continue; | 344 continue; |
| 339 } | 345 } |
| 340 | 346 |
| 341 // Clean up old version directories. | 347 // Clean up old version directories. |
| 342 file_util::FileEnumerator versions_enumerator( | 348 file_util::FileEnumerator versions_enumerator( |
| 343 extension_path, | 349 extension_path, |
| 344 false, // Not recursive. | 350 false, // Not recursive. |
| 345 file_util::FileEnumerator::DIRECTORIES); | 351 file_util::FileEnumerator::DIRECTORIES); |
| 346 for (FilePath version_dir = versions_enumerator.Next(); | 352 for (FilePath version_dir = versions_enumerator.Next(); |
| 347 !version_dir.value().empty(); | 353 !version_dir.value().empty(); |
| 348 version_dir = versions_enumerator.Next()) { | 354 version_dir = versions_enumerator.Next()) { |
| 349 if (version_dir.BaseName() != iter->second.BaseName()) { | 355 if (version_dir.BaseName() != iter->second.BaseName()) { |
| 350 VLOG(1) << "Deleting old version for directory " | 356 VLOG(1) << "Deleting old version for directory " |
| 351 << WideToASCII(version_dir.ToWStringHack()) << "."; | 357 << version_dir.LossyDisplayName() << "."; |
| 352 file_util::Delete(version_dir, true); // Recursive. | 358 file_util::Delete(version_dir, true); // Recursive. |
| 353 } | 359 } |
| 354 } | 360 } |
| 355 } | 361 } |
| 356 } | 362 } |
| 357 | 363 |
| 358 ExtensionMessageBundle* LoadExtensionMessageBundle( | 364 ExtensionMessageBundle* LoadExtensionMessageBundle( |
| 359 const FilePath& extension_path, | 365 const FilePath& extension_path, |
| 360 const std::string& default_locale, | 366 const std::string& default_locale, |
| 361 std::string* error) { | 367 std::string* error) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 if (extension_l10n_util::ShouldSkipValidation(path, locale_path, | 427 if (extension_l10n_util::ShouldSkipValidation(path, locale_path, |
| 422 all_locales)) | 428 all_locales)) |
| 423 continue; | 429 continue; |
| 424 | 430 |
| 425 FilePath messages_path = | 431 FilePath messages_path = |
| 426 locale_path.Append(Extension::kMessagesFilename); | 432 locale_path.Append(Extension::kMessagesFilename); |
| 427 | 433 |
| 428 if (!file_util::PathExists(messages_path)) { | 434 if (!file_util::PathExists(messages_path)) { |
| 429 *error = base::StringPrintf( | 435 *error = base::StringPrintf( |
| 430 "%s %s", errors::kLocalesMessagesFileMissing, | 436 "%s %s", errors::kLocalesMessagesFileMissing, |
| 431 WideToUTF8(messages_path.ToWStringHack()).c_str()); | 437 UTF16ToUTF8(messages_path.LossyDisplayName()).c_str()); |
| 432 return false; | 438 return false; |
| 433 } | 439 } |
| 434 | 440 |
| 435 if (locale_path == default_locale_path) | 441 if (locale_path == default_locale_path) |
| 436 has_default_locale_message_file = true; | 442 has_default_locale_message_file = true; |
| 437 } | 443 } |
| 438 | 444 |
| 439 // Only message file for default locale has to exist. | 445 // Only message file for default locale has to exist. |
| 440 if (!has_default_locale_message_file) { | 446 if (!has_default_locale_message_file) { |
| 441 *error = errors::kLocalesNoDefaultMessages; | 447 *error = errors::kLocalesNoDefaultMessages; |
| 442 return false; | 448 return false; |
| 443 } | 449 } |
| 444 | 450 |
| 445 return true; | 451 return true; |
| 446 } | 452 } |
| 447 | 453 |
| 448 static bool IsScriptValid(const FilePath& path, | 454 static bool IsScriptValid(const FilePath& path, |
| 449 const FilePath& relative_path, | 455 const FilePath& relative_path, |
| 450 int message_id, | 456 int message_id, |
| 451 std::string* error) { | 457 std::string* error) { |
| 452 std::string content; | 458 std::string content; |
| 453 if (!file_util::PathExists(path) || | 459 if (!file_util::PathExists(path) || |
| 454 !file_util::ReadFileToString(path, &content)) { | 460 !file_util::ReadFileToString(path, &content)) { |
| 455 *error = l10n_util::GetStringFUTF8( | 461 *error = l10n_util::GetStringFUTF8( |
| 456 message_id, | 462 message_id, |
| 457 WideToUTF16(relative_path.ToWStringHack())); | 463 relative_path.LossyDisplayName()); |
| 458 return false; | 464 return false; |
| 459 } | 465 } |
| 460 | 466 |
| 461 if (!IsStringUTF8(content)) { | 467 if (!IsStringUTF8(content)) { |
| 462 *error = l10n_util::GetStringFUTF8( | 468 *error = l10n_util::GetStringFUTF8( |
| 463 IDS_EXTENSION_BAD_FILE_ENCODING, | 469 IDS_EXTENSION_BAD_FILE_ENCODING, |
| 464 WideToUTF16(relative_path.ToWStringHack())); | 470 relative_path.LossyDisplayName()); |
| 465 return false; | 471 return false; |
| 466 } | 472 } |
| 467 | 473 |
| 468 return true; | 474 return true; |
| 469 } | 475 } |
| 470 | 476 |
| 471 bool CheckForIllegalFilenames(const FilePath& extension_path, | 477 bool CheckForIllegalFilenames(const FilePath& extension_path, |
| 472 std::string* error) { | 478 std::string* error) { |
| 473 // Reserved underscore names. | 479 // Reserved underscore names. |
| 474 static const FilePath::CharType* reserved_names[] = { | 480 static const FilePath::CharType* reserved_names[] = { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 result, | 603 result, |
| 598 NUM_DIRECTORY_CREATION_RESULTS); | 604 NUM_DIRECTORY_CREATION_RESULTS); |
| 599 | 605 |
| 600 if (result == SUCCESS) | 606 if (result == SUCCESS) |
| 601 return temp_path; | 607 return temp_path; |
| 602 | 608 |
| 603 return FilePath(); | 609 return FilePath(); |
| 604 } | 610 } |
| 605 | 611 |
| 606 } // namespace extension_file_util | 612 } // namespace extension_file_util |
| OLD | NEW |