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 |