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

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

Issue 12316077: 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, 10 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_path.h" 10 #include "base/file_path.h"
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 } 138 }
139 ~ExtensionConfig() { } 139 ~ExtensionConfig() { }
140 140
141 // A whitelist of extensions that can script anywhere. Do not add to this 141 // A whitelist of extensions that can script anywhere. Do not add to this
142 // list (except in tests) without consulting the Extensions team first. 142 // list (except in tests) without consulting the Extensions team first.
143 // Note: Component extensions have this right implicitly and do not need to be 143 // Note: Component extensions have this right implicitly and do not need to be
144 // added to this list. 144 // added to this list.
145 Extension::ScriptingWhitelist scripting_whitelist_; 145 Extension::ScriptingWhitelist scripting_whitelist_;
146 }; 146 };
147 147
148 bool ReadLaunchDimension(const extensions::Manifest* manifest,
149 const char* key,
150 int* target,
151 bool is_valid_container,
152 string16* error) {
153 Value* temp = NULL;
154 if (manifest->Get(key, &temp)) {
155 if (!is_valid_container) {
156 *error = ErrorUtils::FormatErrorMessageUTF16(
157 errors::kInvalidLaunchValueContainer,
158 key);
159 return false;
160 }
161 if (!temp->GetAsInteger(target) || *target < 0) {
162 *target = 0;
163 *error = ErrorUtils::FormatErrorMessageUTF16(
164 errors::kInvalidLaunchValue,
165 key);
166 return false;
167 }
168 }
169 return true;
170 }
171
172 bool ContainsManifestForbiddenPermission(const APIPermissionSet& apis, 148 bool ContainsManifestForbiddenPermission(const APIPermissionSet& apis,
173 string16* error) { 149 string16* error) {
174 CHECK(error); 150 CHECK(error);
175 for (APIPermissionSet::const_iterator i = apis.begin(); 151 for (APIPermissionSet::const_iterator i = apis.begin();
176 i != apis.end(); ++i) { 152 i != apis.end(); ++i) {
177 if ((*i)->ManifestEntryForbidden()) { 153 if ((*i)->ManifestEntryForbidden()) {
178 *error = ErrorUtils::FormatErrorMessageUTF16( 154 *error = ErrorUtils::FormatErrorMessageUTF16(
179 errors::kPermissionNotAllowedInManifest, 155 errors::kPermissionNotAllowedInManifest,
180 (*i)->info()->name()); 156 (*i)->info()->name());
181 return true; 157 return true;
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 std::string path = icons().Get(size, match_type); 812 std::string path = icons().Get(size, match_type);
837 return path.empty() ? ExtensionResource() : GetResource(path); 813 return path.empty() ? ExtensionResource() : GetResource(path);
838 } 814 }
839 815
840 GURL Extension::GetIconURL(int size, 816 GURL Extension::GetIconURL(int size,
841 ExtensionIconSet::MatchType match_type) const { 817 ExtensionIconSet::MatchType match_type) const {
842 std::string path = icons().Get(size, match_type); 818 std::string path = icons().Get(size, match_type);
843 return path.empty() ? GURL() : GetResourceURL(path); 819 return path.empty() ? GURL() : GetResourceURL(path);
844 } 820 }
845 821
846 GURL Extension::GetFullLaunchURL() const {
847 return launch_local_path().empty() ? GURL(launch_web_url()) :
848 url().Resolve(launch_local_path());
849 }
850
851 bool Extension::CanExecuteScriptOnPage(const GURL& document_url, 822 bool Extension::CanExecuteScriptOnPage(const GURL& document_url,
852 const GURL& top_frame_url, 823 const GURL& top_frame_url,
853 int tab_id, 824 int tab_id,
854 const UserScript* script, 825 const UserScript* script,
855 std::string* error) const { 826 std::string* error) const {
856 base::AutoLock auto_lock(runtime_data_lock_); 827 base::AutoLock auto_lock(runtime_data_lock_);
857 // The gallery is special-cased as a restricted URL for scripting to prevent 828 // The gallery is special-cased as a restricted URL for scripting to prevent
858 // access to special JS bindings we expose to the gallery (and avoid things 829 // access to special JS bindings we expose to the gallery (and avoid things
859 // like extensions removing the "report abuse" link). 830 // like extensions removing the "report abuse" link).
860 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing 831 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 } 1122 }
1152 1123
1153 bool Extension::can_be_incognito_enabled() const { 1124 bool Extension::can_be_incognito_enabled() const {
1154 return !is_platform_app(); 1125 return !is_platform_app();
1155 } 1126 }
1156 1127
1157 void Extension::AddWebExtentPattern(const URLPattern& pattern) { 1128 void Extension::AddWebExtentPattern(const URLPattern& pattern) {
1158 extent_.AddPattern(pattern); 1129 extent_.AddPattern(pattern);
1159 } 1130 }
1160 1131
1132 void Extension::ClearWebExtentPatterns() {
1133 extent_.ClearPatterns();
1134 }
1135
1161 bool Extension::is_theme() const { 1136 bool Extension::is_theme() const {
1162 return manifest()->is_theme(); 1137 return manifest()->is_theme();
1163 } 1138 }
1164 1139
1165 bool Extension::is_content_pack() const { 1140 bool Extension::is_content_pack() const {
1166 return !content_pack_site_list_.empty(); 1141 return !content_pack_site_list_.empty();
1167 } 1142 }
1168 1143
1169 ExtensionResource Extension::GetContentPackSiteList() const { 1144 ExtensionResource Extension::GetContentPackSiteList() const {
1170 if (!is_content_pack()) 1145 if (!is_content_pack())
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 scoped_ptr<extensions::Manifest> manifest) 1304 scoped_ptr<extensions::Manifest> manifest)
1330 : manifest_version_(0), 1305 : manifest_version_(0),
1331 incognito_split_mode_(false), 1306 incognito_split_mode_(false),
1332 offline_enabled_(false), 1307 offline_enabled_(false),
1333 converted_from_user_script_(false), 1308 converted_from_user_script_(false),
1334 background_page_is_persistent_(true), 1309 background_page_is_persistent_(true),
1335 allow_background_js_access_(true), 1310 allow_background_js_access_(true),
1336 manifest_(manifest.release()), 1311 manifest_(manifest.release()),
1337 finished_parsing_manifest_(false), 1312 finished_parsing_manifest_(false),
1338 is_storage_isolated_(false), 1313 is_storage_isolated_(false),
1339 launch_container_(extension_misc::LAUNCH_TAB),
1340 launch_width_(0),
1341 launch_height_(0),
1342 display_in_launcher_(true), 1314 display_in_launcher_(true),
1343 display_in_new_tab_page_(true), 1315 display_in_new_tab_page_(true),
1344 wants_file_access_(false), 1316 wants_file_access_(false),
1345 creation_flags_(0) { 1317 creation_flags_(0) {
1346 DCHECK(path.empty() || path.IsAbsolute()); 1318 DCHECK(path.empty() || path.IsAbsolute());
1347 path_ = MaybeNormalizePath(path); 1319 path_ = MaybeNormalizePath(path);
1348 } 1320 }
1349 1321
1350 Extension::~Extension() { 1322 Extension::~Extension() {
1351 } 1323 }
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 version_.reset(new Version(version_str)); 1500 version_.reset(new Version(version_str));
1529 if (!version_->IsValid() || version_->components().size() > 4) { 1501 if (!version_->IsValid() || version_->components().size() > 4) {
1530 *error = ASCIIToUTF16(errors::kInvalidVersion); 1502 *error = ASCIIToUTF16(errors::kInvalidVersion);
1531 return false; 1503 return false;
1532 } 1504 }
1533 return true; 1505 return true;
1534 } 1506 }
1535 1507
1536 bool Extension::LoadAppFeatures(string16* error) { 1508 bool Extension::LoadAppFeatures(string16* error) {
1537 if (!LoadExtent(keys::kWebURLs, &extent_, 1509 if (!LoadExtent(keys::kWebURLs, &extent_,
1538 errors::kInvalidWebURLs, errors::kInvalidWebURL, error) || 1510 errors::kInvalidWebURLs, errors::kInvalidWebURL, error)) {
1539 !LoadLaunchURL(error) ||
1540 !LoadLaunchContainer(error)) {
1541 return false; 1511 return false;
1542 } 1512 }
1543 if (manifest_->HasKey(keys::kDisplayInLauncher) && 1513 if (manifest_->HasKey(keys::kDisplayInLauncher) &&
1544 !manifest_->GetBoolean(keys::kDisplayInLauncher, &display_in_launcher_)) { 1514 !manifest_->GetBoolean(keys::kDisplayInLauncher, &display_in_launcher_)) {
1545 *error = ASCIIToUTF16(errors::kInvalidDisplayInLauncher); 1515 *error = ASCIIToUTF16(errors::kInvalidDisplayInLauncher);
1546 return false; 1516 return false;
1547 } 1517 }
1548 if (manifest_->HasKey(keys::kDisplayInNewTabPage)) { 1518 if (manifest_->HasKey(keys::kDisplayInNewTabPage)) {
1549 if (!manifest_->GetBoolean(keys::kDisplayInNewTabPage, 1519 if (!manifest_->GetBoolean(keys::kDisplayInNewTabPage,
1550 &display_in_new_tab_page_)) { 1520 &display_in_new_tab_page_)) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 return false; 1595 return false;
1626 } 1596 }
1627 pattern.SetPath(pattern.path() + '*'); 1597 pattern.SetPath(pattern.path() + '*');
1628 1598
1629 extent->AddPattern(pattern); 1599 extent->AddPattern(pattern);
1630 } 1600 }
1631 1601
1632 return true; 1602 return true;
1633 } 1603 }
1634 1604
1635 bool Extension::LoadLaunchContainer(string16* error) {
1636 Value* tmp_launcher_container = NULL;
1637 if (!manifest_->Get(keys::kLaunchContainer, &tmp_launcher_container))
1638 return true;
1639
1640 std::string launch_container_string;
1641 if (!tmp_launcher_container->GetAsString(&launch_container_string)) {
1642 *error = ASCIIToUTF16(errors::kInvalidLaunchContainer);
1643 return false;
1644 }
1645
1646 if (launch_container_string == values::kLaunchContainerPanel) {
1647 launch_container_ = extension_misc::LAUNCH_PANEL;
1648 } else if (launch_container_string == values::kLaunchContainerTab) {
1649 launch_container_ = extension_misc::LAUNCH_TAB;
1650 } else {
1651 *error = ASCIIToUTF16(errors::kInvalidLaunchContainer);
1652 return false;
1653 }
1654
1655 bool can_specify_initial_size =
1656 launch_container_ == extension_misc::LAUNCH_PANEL ||
1657 launch_container_ == extension_misc::LAUNCH_WINDOW;
1658
1659 // Validate the container width if present.
1660 if (!ReadLaunchDimension(manifest_.get(),
1661 keys::kLaunchWidth,
1662 &launch_width_,
1663 can_specify_initial_size,
1664 error)) {
1665 return false;
1666 }
1667
1668 // Validate container height if present.
1669 if (!ReadLaunchDimension(manifest_.get(),
1670 keys::kLaunchHeight,
1671 &launch_height_,
1672 can_specify_initial_size,
1673 error)) {
1674 return false;
1675 }
1676
1677 return true;
1678 }
1679
1680 bool Extension::LoadLaunchURL(string16* error) {
1681 Value* temp = NULL;
1682
1683 // launch URL can be either local (to chrome-extension:// root) or an absolute
1684 // web URL.
1685 if (manifest_->Get(keys::kLaunchLocalPath, &temp)) {
1686 if (manifest_->Get(keys::kLaunchWebURL, NULL)) {
1687 *error = ASCIIToUTF16(errors::kLaunchPathAndURLAreExclusive);
1688 return false;
1689 }
1690
1691 if (manifest_->Get(keys::kWebURLs, NULL)) {
1692 *error = ASCIIToUTF16(errors::kLaunchPathAndExtentAreExclusive);
1693 return false;
1694 }
1695
1696 std::string launch_path;
1697 if (!temp->GetAsString(&launch_path)) {
1698 *error = ErrorUtils::FormatErrorMessageUTF16(
1699 errors::kInvalidLaunchValue,
1700 keys::kLaunchLocalPath);
1701 return false;
1702 }
1703
1704 // Ensure the launch path is a valid relative URL.
1705 GURL resolved = url().Resolve(launch_path);
1706 if (!resolved.is_valid() || resolved.GetOrigin() != url()) {
1707 *error = ErrorUtils::FormatErrorMessageUTF16(
1708 errors::kInvalidLaunchValue,
1709 keys::kLaunchLocalPath);
1710 return false;
1711 }
1712
1713 launch_local_path_ = launch_path;
1714 } else if (manifest_->Get(keys::kLaunchWebURL, &temp)) {
1715 std::string launch_url;
1716 if (!temp->GetAsString(&launch_url)) {
1717 *error = ErrorUtils::FormatErrorMessageUTF16(
1718 errors::kInvalidLaunchValue,
1719 keys::kLaunchWebURL);
1720 return false;
1721 }
1722
1723 // Ensure the launch URL is a valid absolute URL and web extent scheme.
1724 GURL url(launch_url);
1725 URLPattern pattern(kValidWebExtentSchemes);
1726 if (!url.is_valid() || !pattern.SetScheme(url.scheme())) {
1727 *error = ErrorUtils::FormatErrorMessageUTF16(
1728 errors::kInvalidLaunchValue,
1729 keys::kLaunchWebURL);
1730 return false;
1731 }
1732
1733 launch_web_url_ = launch_url;
1734 } else if (is_legacy_packaged_app() || is_hosted_app()) {
1735 *error = ASCIIToUTF16(errors::kLaunchURLRequired);
1736 return false;
1737 }
1738
1739 // If there is no extent, we default the extent based on the launch URL.
1740 if (web_extent().is_empty() && !launch_web_url().empty()) {
1741 GURL launch_url(launch_web_url());
1742 URLPattern pattern(kValidWebExtentSchemes);
1743 if (!pattern.SetScheme("*")) {
1744 *error = ErrorUtils::FormatErrorMessageUTF16(
1745 errors::kInvalidLaunchValue,
1746 keys::kLaunchWebURL);
1747 return false;
1748 }
1749 pattern.SetHost(launch_url.host());
1750 pattern.SetPath("/*");
1751 extent_.AddPattern(pattern);
1752 }
1753
1754 // In order for the --apps-gallery-url switch to work with the gallery
1755 // process isolation, we must insert any provided value into the component
1756 // app's launch url and web extent.
1757 if (id() == extension_misc::kWebStoreAppId) {
1758 std::string gallery_url_str = CommandLine::ForCurrentProcess()->
1759 GetSwitchValueASCII(switches::kAppsGalleryURL);
1760
1761 // Empty string means option was not used.
1762 if (!gallery_url_str.empty()) {
1763 GURL gallery_url(gallery_url_str);
1764 OverrideLaunchUrl(gallery_url);
1765 }
1766 } else if (id() == extension_misc::kCloudPrintAppId) {
1767 // In order for the --cloud-print-service switch to work, we must update
1768 // the launch URL and web extent.
1769 // TODO(sanjeevr): Ideally we want to use CloudPrintURL here but that is
1770 // currently under chrome/browser.
1771 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1772 GURL cloud_print_service_url = GURL(command_line.GetSwitchValueASCII(
1773 switches::kCloudPrintServiceURL));
1774 if (!cloud_print_service_url.is_empty()) {
1775 std::string path(
1776 cloud_print_service_url.path() + "/enable_chrome_connector");
1777 GURL::Replacements replacements;
1778 replacements.SetPathStr(path);
1779 GURL cloud_print_enable_connector_url =
1780 cloud_print_service_url.ReplaceComponents(replacements);
1781 OverrideLaunchUrl(cloud_print_enable_connector_url);
1782 }
1783 } else if (id() == extension_misc::kChromeAppId) {
1784 // Override launch url to new tab.
1785 launch_web_url_ = chrome::kChromeUINewTabURL;
1786 extent_.ClearPatterns();
1787 }
1788
1789 return true;
1790 }
1791
1792 bool Extension::LoadSharedFeatures(string16* error) { 1605 bool Extension::LoadSharedFeatures(string16* error) {
1793 if (!LoadDescription(error) || 1606 if (!LoadDescription(error) ||
1794 !LoadIcons(error) || 1607 !LoadIcons(error) ||
1795 !ManifestHandler::ParseExtension(this, error) || 1608 !ManifestHandler::ParseExtension(this, error) ||
1796 !LoadPlugins(error) || 1609 !LoadPlugins(error) ||
1797 !LoadNaClModules(error) || 1610 !LoadNaClModules(error) ||
1798 !LoadSandboxedPages(error) || 1611 !LoadSandboxedPages(error) ||
1799 !LoadRequirements(error) || 1612 !LoadRequirements(error) ||
1800 !LoadOfflineEnabled(error) || 1613 !LoadOfflineEnabled(error) ||
1801 // LoadBackgroundScripts() must be called before LoadBackgroundPage(). 1614 // LoadBackgroundScripts() must be called before LoadBackgroundPage().
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
2566 2379
2567 if (ActionInfo::GetBrowserActionInfo(this)) 2380 if (ActionInfo::GetBrowserActionInfo(this))
2568 ++num_surfaces; 2381 ++num_surfaces;
2569 2382
2570 if (is_app()) 2383 if (is_app())
2571 ++num_surfaces; 2384 ++num_surfaces;
2572 2385
2573 return num_surfaces > 1; 2386 return num_surfaces > 1;
2574 } 2387 }
2575 2388
2576 void Extension::OverrideLaunchUrl(const GURL& override_url) {
2577 GURL new_url(override_url);
2578 if (!new_url.is_valid()) {
2579 DLOG(WARNING) << "Invalid override url given for " << name();
2580 } else {
2581 if (new_url.has_port()) {
2582 DLOG(WARNING) << "Override URL passed for " << name()
2583 << " should not contain a port. Removing it.";
2584
2585 GURL::Replacements remove_port;
2586 remove_port.ClearPort();
2587 new_url = new_url.ReplaceComponents(remove_port);
2588 }
2589
2590 launch_web_url_ = new_url.spec();
2591
2592 URLPattern pattern(kValidWebExtentSchemes);
2593 URLPattern::ParseResult result = pattern.Parse(new_url.spec());
2594 DCHECK_EQ(result, URLPattern::PARSE_SUCCESS);
2595 pattern.SetPath(pattern.path() + '*');
2596 extent_.AddPattern(pattern);
2597 }
2598 }
2599
2600 bool Extension::CanSpecifyExperimentalPermission() const { 2389 bool Extension::CanSpecifyExperimentalPermission() const {
2601 if (location() == Manifest::COMPONENT) 2390 if (location() == Manifest::COMPONENT)
2602 return true; 2391 return true;
2603 2392
2604 if (CommandLine::ForCurrentProcess()->HasSwitch( 2393 if (CommandLine::ForCurrentProcess()->HasSwitch(
2605 switches::kEnableExperimentalExtensionApis)) { 2394 switches::kEnableExperimentalExtensionApis)) {
2606 return true; 2395 return true;
2607 } 2396 }
2608 2397
2609 // We rely on the webstore to check access to experimental. This way we can 2398 // We rely on the webstore to check access to experimental. This way we can
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2727 2516
2728 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( 2517 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
2729 const Extension* extension, 2518 const Extension* extension,
2730 const PermissionSet* permissions, 2519 const PermissionSet* permissions,
2731 Reason reason) 2520 Reason reason)
2732 : reason(reason), 2521 : reason(reason),
2733 extension(extension), 2522 extension(extension),
2734 permissions(permissions) {} 2523 permissions(permissions) {}
2735 2524
2736 } // namespace extensions 2525 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698