Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Side by Side Diff: chrome/common/extensions/extension.cc

Issue 14241002: Move the parsing of app.launch related keys out of Extension class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/extension.h" 5 #include "chrome/common/extensions/extension.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 } 113 }
114 ~ExtensionConfig() { } 114 ~ExtensionConfig() { }
115 115
116 // A whitelist of extensions that can script anywhere. Do not add to this 116 // A whitelist of extensions that can script anywhere. Do not add to this
117 // list (except in tests) without consulting the Extensions team first. 117 // list (except in tests) without consulting the Extensions team first.
118 // Note: Component extensions have this right implicitly and do not need to be 118 // Note: Component extensions have this right implicitly and do not need to be
119 // added to this list. 119 // added to this list.
120 Extension::ScriptingWhitelist scripting_whitelist_; 120 Extension::ScriptingWhitelist scripting_whitelist_;
121 }; 121 };
122 122
123 bool ReadLaunchDimension(const extensions::Manifest* manifest,
124 const char* key,
125 int* target,
126 bool is_valid_container,
127 string16* error) {
128 const Value* temp = NULL;
129 if (manifest->Get(key, &temp)) {
130 if (!is_valid_container) {
131 *error = ErrorUtils::FormatErrorMessageUTF16(
132 errors::kInvalidLaunchValueContainer,
133 key);
134 return false;
135 }
136 if (!temp->GetAsInteger(target) || *target < 0) {
137 *target = 0;
138 *error = ErrorUtils::FormatErrorMessageUTF16(
139 errors::kInvalidLaunchValue,
140 key);
141 return false;
142 }
143 }
144 return true;
145 }
146
147 bool ContainsManifestForbiddenPermission(const APIPermissionSet& apis, 123 bool ContainsManifestForbiddenPermission(const APIPermissionSet& apis,
148 string16* error) { 124 string16* error) {
149 CHECK(error); 125 CHECK(error);
150 for (APIPermissionSet::const_iterator i = apis.begin(); 126 for (APIPermissionSet::const_iterator i = apis.begin();
151 i != apis.end(); ++i) { 127 i != apis.end(); ++i) {
152 if ((*i)->ManifestEntryForbidden()) { 128 if ((*i)->ManifestEntryForbidden()) {
153 *error = ErrorUtils::FormatErrorMessageUTF16( 129 *error = ErrorUtils::FormatErrorMessageUTF16(
154 errors::kPermissionNotAllowedInManifest, 130 errors::kPermissionNotAllowedInManifest,
155 (*i)->info()->name()); 131 (*i)->info()->name());
156 return true; 132 return true;
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 iter != browser_action->default_icon.map().end(); 683 iter != browser_action->default_icon.map().end();
708 ++iter) { 684 ++iter) {
709 image_paths.insert( 685 image_paths.insert(
710 base::FilePath::FromWStringHack(UTF8ToWide(iter->second))); 686 base::FilePath::FromWStringHack(UTF8ToWide(iter->second)));
711 } 687 }
712 } 688 }
713 689
714 return image_paths; 690 return image_paths;
715 } 691 }
716 692
717 GURL Extension::GetFullLaunchURL() const {
718 return launch_local_path().empty() ? GURL(launch_web_url()) :
719 url().Resolve(launch_local_path());
720 }
721
722 bool Extension::CanExecuteScriptOnPage(const GURL& document_url, 693 bool Extension::CanExecuteScriptOnPage(const GURL& document_url,
723 const GURL& top_frame_url, 694 const GURL& top_frame_url,
724 int tab_id, 695 int tab_id,
725 const UserScript* script, 696 const UserScript* script,
726 std::string* error) const { 697 std::string* error) const {
727 base::AutoLock auto_lock(runtime_data_lock_); 698 base::AutoLock auto_lock(runtime_data_lock_);
728 // The gallery is special-cased as a restricted URL for scripting to prevent 699 // The gallery is special-cased as a restricted URL for scripting to prevent
729 // access to special JS bindings we expose to the gallery (and avoid things 700 // access to special JS bindings we expose to the gallery (and avoid things
730 // like extensions removing the "report abuse" link). 701 // like extensions removing the "report abuse" link).
731 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing 702 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 } 995 }
1025 996
1026 bool Extension::can_be_incognito_enabled() const { 997 bool Extension::can_be_incognito_enabled() const {
1027 return !is_platform_app(); 998 return !is_platform_app();
1028 } 999 }
1029 1000
1030 void Extension::AddWebExtentPattern(const URLPattern& pattern) { 1001 void Extension::AddWebExtentPattern(const URLPattern& pattern) {
1031 extent_.AddPattern(pattern); 1002 extent_.AddPattern(pattern);
1032 } 1003 }
1033 1004
1005 void Extension::ClearWebExtentPatterns() {
1006 extent_.ClearPatterns();
1007 }
1008
1034 bool Extension::is_theme() const { 1009 bool Extension::is_theme() const {
1035 return manifest()->is_theme(); 1010 return manifest()->is_theme();
1036 } 1011 }
1037 1012
1038 Extension::RuntimeData::RuntimeData() {} 1013 Extension::RuntimeData::RuntimeData() {}
1039 Extension::RuntimeData::RuntimeData(const PermissionSet* active) 1014 Extension::RuntimeData::RuntimeData(const PermissionSet* active)
1040 : active_permissions_(active) {} 1015 : active_permissions_(active) {}
1041 Extension::RuntimeData::~RuntimeData() {} 1016 Extension::RuntimeData::~RuntimeData() {}
1042 1017
1043 void Extension::RuntimeData::SetActivePermissions( 1018 void Extension::RuntimeData::SetActivePermissions(
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 // See http://b/4946060 for more details. 1096 // See http://b/4946060 for more details.
1122 return id == std::string("nckgahadagoaajjgafhacjanaoiihapd"); 1097 return id == std::string("nckgahadagoaajjgafhacjanaoiihapd");
1123 } 1098 }
1124 1099
1125 Extension::Extension(const base::FilePath& path, 1100 Extension::Extension(const base::FilePath& path,
1126 scoped_ptr<extensions::Manifest> manifest) 1101 scoped_ptr<extensions::Manifest> manifest)
1127 : manifest_version_(0), 1102 : manifest_version_(0),
1128 converted_from_user_script_(false), 1103 converted_from_user_script_(false),
1129 manifest_(manifest.release()), 1104 manifest_(manifest.release()),
1130 finished_parsing_manifest_(false), 1105 finished_parsing_manifest_(false),
1131 launch_container_(extension_misc::LAUNCH_TAB),
1132 launch_width_(0),
1133 launch_height_(0),
1134 display_in_launcher_(true), 1106 display_in_launcher_(true),
1135 display_in_new_tab_page_(true), 1107 display_in_new_tab_page_(true),
1136 wants_file_access_(false), 1108 wants_file_access_(false),
1137 creation_flags_(0) { 1109 creation_flags_(0) {
1138 DCHECK(path.empty() || path.IsAbsolute()); 1110 DCHECK(path.empty() || path.IsAbsolute());
1139 path_ = id_util::MaybeNormalizePath(path); 1111 path_ = id_util::MaybeNormalizePath(path);
1140 } 1112 }
1141 1113
1142 Extension::~Extension() { 1114 Extension::~Extension() {
1143 } 1115 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 version_.reset(new Version(version_str)); 1247 version_.reset(new Version(version_str));
1276 if (!version_->IsValid() || version_->components().size() > 4) { 1248 if (!version_->IsValid() || version_->components().size() > 4) {
1277 *error = ASCIIToUTF16(errors::kInvalidVersion); 1249 *error = ASCIIToUTF16(errors::kInvalidVersion);
1278 return false; 1250 return false;
1279 } 1251 }
1280 return true; 1252 return true;
1281 } 1253 }
1282 1254
1283 bool Extension::LoadAppFeatures(string16* error) { 1255 bool Extension::LoadAppFeatures(string16* error) {
1284 if (!LoadExtent(keys::kWebURLs, &extent_, 1256 if (!LoadExtent(keys::kWebURLs, &extent_,
1285 errors::kInvalidWebURLs, errors::kInvalidWebURL, error) || 1257 errors::kInvalidWebURLs, errors::kInvalidWebURL, error)) {
1286 !LoadLaunchURL(error) ||
1287 !LoadLaunchContainer(error)) {
1288 return false; 1258 return false;
1289 } 1259 }
1290 if (manifest_->HasKey(keys::kDisplayInLauncher) && 1260 if (manifest_->HasKey(keys::kDisplayInLauncher) &&
1291 !manifest_->GetBoolean(keys::kDisplayInLauncher, &display_in_launcher_)) { 1261 !manifest_->GetBoolean(keys::kDisplayInLauncher, &display_in_launcher_)) {
1292 *error = ASCIIToUTF16(errors::kInvalidDisplayInLauncher); 1262 *error = ASCIIToUTF16(errors::kInvalidDisplayInLauncher);
1293 return false; 1263 return false;
1294 } 1264 }
1295 if (manifest_->HasKey(keys::kDisplayInNewTabPage)) { 1265 if (manifest_->HasKey(keys::kDisplayInNewTabPage)) {
1296 if (!manifest_->GetBoolean(keys::kDisplayInNewTabPage, 1266 if (!manifest_->GetBoolean(keys::kDisplayInNewTabPage,
1297 &display_in_new_tab_page_)) { 1267 &display_in_new_tab_page_)) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1372 return false; 1342 return false;
1373 } 1343 }
1374 pattern.SetPath(pattern.path() + '*'); 1344 pattern.SetPath(pattern.path() + '*');
1375 1345
1376 extent->AddPattern(pattern); 1346 extent->AddPattern(pattern);
1377 } 1347 }
1378 1348
1379 return true; 1349 return true;
1380 } 1350 }
1381 1351
1382 bool Extension::LoadLaunchContainer(string16* error) {
1383 const Value* tmp_launcher_container = NULL;
1384 if (!manifest_->Get(keys::kLaunchContainer, &tmp_launcher_container))
1385 return true;
1386
1387 std::string launch_container_string;
1388 if (!tmp_launcher_container->GetAsString(&launch_container_string)) {
1389 *error = ASCIIToUTF16(errors::kInvalidLaunchContainer);
1390 return false;
1391 }
1392
1393 if (launch_container_string == values::kLaunchContainerPanel) {
1394 launch_container_ = extension_misc::LAUNCH_PANEL;
1395 } else if (launch_container_string == values::kLaunchContainerTab) {
1396 launch_container_ = extension_misc::LAUNCH_TAB;
1397 } else {
1398 *error = ASCIIToUTF16(errors::kInvalidLaunchContainer);
1399 return false;
1400 }
1401
1402 bool can_specify_initial_size =
1403 launch_container_ == extension_misc::LAUNCH_PANEL ||
1404 launch_container_ == extension_misc::LAUNCH_WINDOW;
1405
1406 // Validate the container width if present.
1407 if (!ReadLaunchDimension(manifest_.get(),
1408 keys::kLaunchWidth,
1409 &launch_width_,
1410 can_specify_initial_size,
1411 error)) {
1412 return false;
1413 }
1414
1415 // Validate container height if present.
1416 if (!ReadLaunchDimension(manifest_.get(),
1417 keys::kLaunchHeight,
1418 &launch_height_,
1419 can_specify_initial_size,
1420 error)) {
1421 return false;
1422 }
1423
1424 return true;
1425 }
1426
1427 bool Extension::LoadLaunchURL(string16* error) {
1428 const Value* temp = NULL;
1429
1430 // launch URL can be either local (to chrome-extension:// root) or an absolute
1431 // web URL.
1432 if (manifest_->Get(keys::kLaunchLocalPath, &temp)) {
1433 if (manifest_->Get(keys::kLaunchWebURL, NULL)) {
1434 *error = ASCIIToUTF16(errors::kLaunchPathAndURLAreExclusive);
1435 return false;
1436 }
1437
1438 if (manifest_->Get(keys::kWebURLs, NULL)) {
1439 *error = ASCIIToUTF16(errors::kLaunchPathAndExtentAreExclusive);
1440 return false;
1441 }
1442
1443 std::string launch_path;
1444 if (!temp->GetAsString(&launch_path)) {
1445 *error = ErrorUtils::FormatErrorMessageUTF16(
1446 errors::kInvalidLaunchValue,
1447 keys::kLaunchLocalPath);
1448 return false;
1449 }
1450
1451 // Ensure the launch path is a valid relative URL.
1452 GURL resolved = url().Resolve(launch_path);
1453 if (!resolved.is_valid() || resolved.GetOrigin() != url()) {
1454 *error = ErrorUtils::FormatErrorMessageUTF16(
1455 errors::kInvalidLaunchValue,
1456 keys::kLaunchLocalPath);
1457 return false;
1458 }
1459
1460 launch_local_path_ = launch_path;
1461 } else if (manifest_->Get(keys::kLaunchWebURL, &temp)) {
1462 std::string launch_url;
1463 if (!temp->GetAsString(&launch_url)) {
1464 *error = ErrorUtils::FormatErrorMessageUTF16(
1465 errors::kInvalidLaunchValue,
1466 keys::kLaunchWebURL);
1467 return false;
1468 }
1469
1470 // Ensure the launch URL is a valid absolute URL and web extent scheme.
1471 GURL url(launch_url);
1472 URLPattern pattern(kValidWebExtentSchemes);
1473 if (!url.is_valid() || !pattern.SetScheme(url.scheme())) {
1474 *error = ErrorUtils::FormatErrorMessageUTF16(
1475 errors::kInvalidLaunchValue,
1476 keys::kLaunchWebURL);
1477 return false;
1478 }
1479
1480 launch_web_url_ = launch_url;
1481 } else if (is_legacy_packaged_app() || is_hosted_app()) {
1482 *error = ASCIIToUTF16(errors::kLaunchURLRequired);
1483 return false;
1484 }
1485
1486 // If there is no extent, we default the extent based on the launch URL.
1487 if (web_extent().is_empty() && !launch_web_url().empty()) {
1488 GURL launch_url(launch_web_url());
1489 URLPattern pattern(kValidWebExtentSchemes);
1490 if (!pattern.SetScheme("*")) {
1491 *error = ErrorUtils::FormatErrorMessageUTF16(
1492 errors::kInvalidLaunchValue,
1493 keys::kLaunchWebURL);
1494 return false;
1495 }
1496 pattern.SetHost(launch_url.host());
1497 pattern.SetPath("/*");
1498 extent_.AddPattern(pattern);
1499 }
1500
1501 // In order for the --apps-gallery-url switch to work with the gallery
1502 // process isolation, we must insert any provided value into the component
1503 // app's launch url and web extent.
1504 if (id() == extension_misc::kWebStoreAppId) {
1505 std::string gallery_url_str = CommandLine::ForCurrentProcess()->
1506 GetSwitchValueASCII(switches::kAppsGalleryURL);
1507
1508 // Empty string means option was not used.
1509 if (!gallery_url_str.empty()) {
1510 GURL gallery_url(gallery_url_str);
1511 OverrideLaunchUrl(gallery_url);
1512 }
1513 } else if (id() == extension_misc::kCloudPrintAppId) {
1514 // In order for the --cloud-print-service switch to work, we must update
1515 // the launch URL and web extent.
1516 // TODO(sanjeevr): Ideally we want to use CloudPrintURL here but that is
1517 // currently under chrome/browser.
1518 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1519 GURL cloud_print_service_url = GURL(command_line.GetSwitchValueASCII(
1520 switches::kCloudPrintServiceURL));
1521 if (!cloud_print_service_url.is_empty()) {
1522 std::string path(
1523 cloud_print_service_url.path() + "/enable_chrome_connector");
1524 GURL::Replacements replacements;
1525 replacements.SetPathStr(path);
1526 GURL cloud_print_enable_connector_url =
1527 cloud_print_service_url.ReplaceComponents(replacements);
1528 OverrideLaunchUrl(cloud_print_enable_connector_url);
1529 }
1530 } else if (id() == extension_misc::kChromeAppId) {
1531 // Override launch url to new tab.
1532 launch_web_url_ = chrome::kChromeUINewTabURL;
1533 extent_.ClearPatterns();
1534 }
1535
1536 return true;
1537 }
1538
1539 bool Extension::LoadSharedFeatures(string16* error) { 1352 bool Extension::LoadSharedFeatures(string16* error) {
1540 if (!LoadDescription(error) || 1353 if (!LoadDescription(error) ||
1541 !ManifestHandler::ParseExtension(this, error) || 1354 !ManifestHandler::ParseExtension(this, error) ||
1542 !LoadNaClModules(error)) 1355 !LoadNaClModules(error))
1543 return false; 1356 return false;
1544 1357
1545 return true; 1358 return true;
1546 } 1359 }
1547 1360
1548 bool Extension::LoadDescription(string16* error) { 1361 bool Extension::LoadDescription(string16* error) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 1441
1629 if (ActionInfo::GetBrowserActionInfo(this)) 1442 if (ActionInfo::GetBrowserActionInfo(this))
1630 ++num_surfaces; 1443 ++num_surfaces;
1631 1444
1632 if (is_app()) 1445 if (is_app())
1633 ++num_surfaces; 1446 ++num_surfaces;
1634 1447
1635 return num_surfaces > 1; 1448 return num_surfaces > 1;
1636 } 1449 }
1637 1450
1638 void Extension::OverrideLaunchUrl(const GURL& override_url) {
1639 GURL new_url(override_url);
1640 if (!new_url.is_valid()) {
1641 DLOG(WARNING) << "Invalid override url given for " << name();
1642 } else {
1643 if (new_url.has_port()) {
1644 DLOG(WARNING) << "Override URL passed for " << name()
1645 << " should not contain a port. Removing it.";
1646
1647 GURL::Replacements remove_port;
1648 remove_port.ClearPort();
1649 new_url = new_url.ReplaceComponents(remove_port);
1650 }
1651
1652 launch_web_url_ = new_url.spec();
1653
1654 URLPattern pattern(kValidWebExtentSchemes);
1655 URLPattern::ParseResult result = pattern.Parse(new_url.spec());
1656 DCHECK_EQ(result, URLPattern::PARSE_SUCCESS);
1657 pattern.SetPath(pattern.path() + '*');
1658 extent_.AddPattern(pattern);
1659 }
1660 }
1661
1662 bool Extension::CanSpecifyExperimentalPermission() const { 1451 bool Extension::CanSpecifyExperimentalPermission() const {
1663 if (location() == Manifest::COMPONENT) 1452 if (location() == Manifest::COMPONENT)
1664 return true; 1453 return true;
1665 1454
1666 if (CommandLine::ForCurrentProcess()->HasSwitch( 1455 if (CommandLine::ForCurrentProcess()->HasSwitch(
1667 switches::kEnableExperimentalExtensionApis)) { 1456 switches::kEnableExperimentalExtensionApis)) {
1668 return true; 1457 return true;
1669 } 1458 }
1670 1459
1671 // We rely on the webstore to check access to experimental. This way we can 1460 // We rely on the webstore to check access to experimental. This way we can
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1801 1590
1802 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( 1591 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
1803 const Extension* extension, 1592 const Extension* extension,
1804 const PermissionSet* permissions, 1593 const PermissionSet* permissions,
1805 Reason reason) 1594 Reason reason)
1806 : reason(reason), 1595 : reason(reason),
1807 extension(extension), 1596 extension(extension),
1808 permissions(permissions) {} 1597 permissions(permissions) {}
1809 1598
1810 } // namespace extensions 1599 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698