12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/version.h"
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/crx_file/id_util.h"
24a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "content/public/common/url_constants.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/error_utils.h"
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h"
28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h"
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handler.h"
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/manifest_handlers/permissions_parser.h"
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "extensions/common/permissions/permission_set.h"
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "extensions/common/permissions/permissions_info.h"
34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "extensions/common/switches.h"
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/url_pattern.h"
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/base/filename_util.h"
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/url_util.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace keys = manifest_keys;
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace values = manifest_values;
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace errors = manifest_errors;
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kModernManifestVersion = 2;
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kPEMOutputColumns = 64;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// KEY MARKERS
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kKeyBeginHeaderMarker[] = "-----BEGIN";
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kKeyBeginFooterMarker[] = "-----END";
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kKeyInfoEndMarker[] = "KEY-----";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPublic[] = "PUBLIC";
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrivate[] = "PRIVATE";
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ContainsReservedCharacters(const base::FilePath& path) {
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // We should disallow backslash '\\' as file path separator even on Windows,
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // because the backslash is not regarded as file path separator on Linux/Mac.
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Extensions are cross-platform.
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Since FilePath uses backslash '\\' as file path separator on Windows, so we
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // need to check manually.
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (path.value().find('\\') != path.value().npos)
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return true;
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return !net::IsSafePortableRelativePath(path);
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const int Extension::kInitFromValueFlagBits = 13;
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char Extension::kMimeType[] = "application/x-chrome-extension";
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int Extension::kValidWebExtentSchemes =
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int Extension::kValidHostPermissionSchemes = URLPattern::SCHEME_CHROMEUI |
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   URLPattern::SCHEME_HTTP |
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   URLPattern::SCHEME_HTTPS |
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   URLPattern::SCHEME_FILE |
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   URLPattern::SCHEME_FTP;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Extension
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<Extension> Extension::Create(const base::FilePath& path,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           Manifest::Location location,
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                           const base::DictionaryValue& value,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int flags,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           std::string* utf8_error) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Extension::Create(path,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           location,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           value,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           flags,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           std::string(),  // ID is ignored if empty.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           utf8_error);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(sungguk): Continue removing std::string errors and replacing
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// with base::string16. See http://crbug.com/71980.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<Extension> Extension::Create(const base::FilePath& path,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           Manifest::Location location,
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                           const base::DictionaryValue& value,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int flags,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const std::string& explicit_id,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           std::string* utf8_error) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(utf8_error);
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 error;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<extensions::Manifest> manifest(
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new extensions::Manifest(
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          location, scoped_ptr<base::DictionaryValue>(value.DeepCopy())));
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!InitExtensionID(manifest.get(), path, explicit_id, flags, &error)) {
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *utf8_error = base::UTF16ToUTF8(error);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<InstallWarning> install_warnings;
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!manifest->ValidateManifest(utf8_error, &install_warnings)) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> extension = new Extension(path, manifest.Pass());
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension->install_warnings_.swap(install_warnings);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension->InitFromValue(flags, &error)) {
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *utf8_error = base::UTF16ToUTF8(error);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Manifest::Type Extension::GetType() const {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return converted_from_user_script() ?
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Manifest::TYPE_USER_SCRIPT : manifest_->type();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL Extension::GetResourceURL(const GURL& extension_url,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& relative_path) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(extension_url.SchemeIs(extensions::kExtensionScheme));
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ("/", extension_url.path());
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string path = relative_path;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the relative path starts with "/", it is "absolute" relative to the
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extension base directory, but extension_url is already specified to refer
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to that base directory, so strip the leading "/" if present.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (relative_path.size() > 0 && relative_path[0] == '/')
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path = relative_path.substr(1);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL ret_val = GURL(extension_url.spec() + path);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(StartsWithASCII(ret_val.spec(), extension_url.spec(), false));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret_val;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Extension::ResourceMatches(const URLPatternSet& pattern_set,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& resource) const {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pattern_set.MatchesURL(extension_url_.Resolve(resource));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionResource Extension::GetResource(
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& relative_path) const {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string new_path = relative_path;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have some legacy data where resources have leading slashes.
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See: http://crbug.com/121164
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!new_path.empty() && new_path.at(0) == '/')
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    new_path.erase(0, 1);
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::FilePath relative_file_path = base::FilePath::FromUTF8Unsafe(new_path);
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (ContainsReservedCharacters(relative_file_path))
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return ExtensionResource();
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionResource r(id(), path(), relative_file_path);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if ((creation_flags() & Extension::FOLLOW_SYMLINKS_ANYWHERE)) {
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    r.set_follow_symlinks_anywhere();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return r;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionResource Extension::GetResource(
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& relative_file_path) const {
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (ContainsReservedCharacters(relative_file_path))
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return ExtensionResource();
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionResource r(id(), path(), relative_file_path);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if ((creation_flags() & Extension::FOLLOW_SYMLINKS_ANYWHERE)) {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    r.set_follow_symlinks_anywhere();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return r;
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(rafaelw): Move ParsePEMKeyBytes, ProducePEM & FormatPEMForOutput to a
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// util class in base:
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// http://code.google.com/p/chromium/issues/detail?id=13572
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::ParsePEMKeyBytes(const std::string& input,
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 std::string* output) {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(output);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!output)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (input.length() == 0)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string working = input;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (StartsWithASCII(working, kKeyBeginHeaderMarker, true)) {
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    working = base::CollapseWhitespaceASCII(working, true);
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t header_pos = working.find(kKeyInfoEndMarker,
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sizeof(kKeyBeginHeaderMarker) - 1);
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (header_pos == std::string::npos)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t start_pos = header_pos + sizeof(kKeyInfoEndMarker) - 1;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t end_pos = working.rfind(kKeyBeginFooterMarker);
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (end_pos == std::string::npos)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (start_pos >= end_pos)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    working = working.substr(start_pos, end_pos - start_pos);
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (working.length() == 0)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::Base64Decode(working, output);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::ProducePEM(const std::string& input, std::string* output) {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(output);
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (input.empty())
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::Base64Encode(input, output);
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return true;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::FormatPEMForFileOutput(const std::string& input,
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       std::string* output,
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       bool is_public) {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(output);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (input.length() == 0)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *output = "";
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append(kKeyBeginHeaderMarker);
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append(" ");
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append(is_public ? kPublic : kPrivate);
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append(" ");
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append(kKeyInfoEndMarker);
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append("\n");
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < input.length(); ) {
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int slice = std::min<int>(input.length() - i, kPEMOutputColumns);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    output->append(input.substr(i, slice));
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    output->append("\n");
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    i += slice;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append(kKeyBeginFooterMarker);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append(" ");
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append(is_public ? kPublic : kPrivate);
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append(" ");
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append(kKeyInfoEndMarker);
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  output->append("\n");
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) {
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GURL(std::string(extensions::kExtensionScheme) +
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              url::kStandardSchemeSeparator + extension_id + "/");
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::ShowConfigureContextMenus() const {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't show context menu for component extensions. We might want to show
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // options for component extension button but now there is no component
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // extension with options. All other menu items like uninstall have
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // no sense for component extensions.
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return location() != Manifest::COMPONENT &&
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         location() != Manifest::EXTERNAL_COMPONENT;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::OverlapsWithOrigin(const GURL& origin) const {
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (url() == origin)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (web_extent().is_empty())
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: patterns and extents ignore port numbers.
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLPattern origin_only_pattern(kValidWebExtentSchemes);
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!origin_only_pattern.SetScheme(origin.scheme()))
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  origin_only_pattern.SetHost(origin.host());
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  origin_only_pattern.SetPath("/*");
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  URLPatternSet origin_only_pattern_list;
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  origin_only_pattern_list.AddPattern(origin_only_pattern);
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return web_extent().OverlapsWith(origin_only_pattern_list);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::RequiresSortOrdinal() const {
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return is_app() && (display_in_launcher_ || display_in_new_tab_page_);
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::ShouldDisplayInAppLauncher() const {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only apps should be displayed in the launcher.
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return is_app() && display_in_launcher_;
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::ShouldDisplayInNewTabPage() const {
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Only apps should be displayed on the NTP.
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return is_app() && display_in_new_tab_page_;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::ShouldDisplayInExtensionSettings() const {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't show for themes since the settings UI isn't really useful for them.
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_theme())
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Don't show component extensions and invisible apps.
3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (ShouldNotBeVisible())
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Always show unpacked extensions and apps.
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (Manifest::IsUnpackedLocation(location()))
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Unless they are unpacked, never show hosted apps. Note: We intentionally
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // show packaged apps and platform apps because there are some pieces of
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // functionality that are only available in chrome://extensions/ but which
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // are needed for packaged and platform apps. For example, inspecting
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // background pages. See http://crbug.com/116134.
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_hosted_app())
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool Extension::ShouldNotBeVisible() const {
3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Don't show component extensions because they are only extensions as an
3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // implementation detail of Chrome.
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (extensions::Manifest::IsComponentLocation(location()) &&
3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          switches::kShowComponentExtensionOptions)) {
3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return true;
3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Always show unpacked extensions and apps.
3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (Manifest::IsUnpackedLocation(location()))
3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Don't show apps that aren't visible in either launcher or ntp.
3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (is_app() && !ShouldDisplayInAppLauncher() && !ShouldDisplayInNewTabPage())
3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return true;
3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return false;
3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Extension::ManifestData* Extension::GetManifestData(const std::string& key)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const {
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(finished_parsing_manifest_ || thread_checker_.CalledOnValidThread());
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ManifestDataMap::const_iterator iter = manifest_data_.find(key);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter != manifest_data_.end())
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return iter->second.get();
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Extension::SetManifestData(const std::string& key,
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                Extension::ManifestData* data) {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!finished_parsing_manifest_ && thread_checker_.CalledOnValidThread());
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manifest_data_[key] = linked_ptr<ManifestData>(data);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Manifest::Location Extension::location() const {
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return manifest_->location();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::string& Extension::id() const {
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return manifest_->extension_id();
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::string Extension::VersionString() const {
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return version()->GetString();
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Extension::AddInstallWarning(const InstallWarning& new_warning) {
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  install_warnings_.push_back(new_warning);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Extension::AddInstallWarnings(
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<InstallWarning>& new_warnings) {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  install_warnings_.insert(install_warnings_.end(),
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           new_warnings.begin(), new_warnings.end());
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::is_app() const {
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return manifest()->is_app();
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::is_platform_app() const {
402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return manifest()->is_platform_app();
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::is_hosted_app() const {
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return manifest()->is_hosted_app();
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::is_legacy_packaged_app() const {
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return manifest()->is_legacy_packaged_app();
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::is_extension() const {
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return manifest()->is_extension();
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool Extension::is_shared_module() const {
418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return manifest()->is_shared_module();
419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool Extension::is_theme() const {
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return manifest()->is_theme();
423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::can_be_incognito_enabled() const {
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Only component platform apps are supported in incognito.
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !is_platform_app() || location() == Manifest::COMPONENT;
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Extension::AddWebExtentPattern(const URLPattern& pattern) {
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Bookmark apps are permissionless.
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (from_bookmark())
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extent_.AddPattern(pattern);
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::InitExtensionID(extensions::Manifest* manifest,
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const base::FilePath& path,
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const std::string& explicit_id,
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                int creation_flags,
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                base::string16* error) {
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!explicit_id.empty()) {
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    manifest->set_extension_id(explicit_id);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (manifest->HasKey(keys::kPublicKey)) {
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string public_key;
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string public_key_bytes;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!manifest->GetString(keys::kPublicKey, &public_key) ||
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !ParsePEMKeyBytes(public_key, &public_key_bytes)) {
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error = base::ASCIIToUTF16(errors::kInvalidKey);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
45703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::string extension_id = crx_file::id_util::GenerateId(public_key_bytes);
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    manifest->set_extension_id(extension_id);
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (creation_flags & REQUIRE_KEY) {
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error = base::ASCIIToUTF16(errors::kInvalidKey);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If there is a path, we generate the ID from it. This is useful for
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // development mode, because it keeps the ID stable across restarts and
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // reloading the extension.
46903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::string extension_id = crx_file::id_util::GenerateIdForPath(path);
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (extension_id.empty()) {
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED() << "Could not create ID from path.";
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    manifest->set_extension_id(extension_id);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Extension::Extension(const base::FilePath& path,
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     scoped_ptr<extensions::Manifest> manifest)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : manifest_version_(0),
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      converted_from_user_script_(false),
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      manifest_(manifest.release()),
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      finished_parsing_manifest_(false),
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      display_in_launcher_(true),
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      display_in_new_tab_page_(true),
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      wants_file_access_(false),
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      creation_flags_(0) {
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(path.empty() || path.IsAbsolute());
49003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  path_ = crx_file::id_util::MaybeNormalizePath(path);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Extension::~Extension() {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Extension::InitFromValue(int flags, base::string16* error) {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(error);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  creation_flags_ = flags;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Important to load manifest version first because many other features
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // depend on its value.
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!LoadManifestVersion(error))
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!LoadRequiredFeatures(error))
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We don't need to validate because InitExtensionID already did that.
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manifest_->GetString(keys::kPublicKey, &public_key_);
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extension_url_ = Extension::GetBaseURLFromExtensionId(id());
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load App settings. LoadExtent at least has to be done before
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ParsePermissions(), because the valid permissions depend on what type of
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // package this is.
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_app() && !LoadAppFeatures(error))
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  permissions_parser_.reset(new PermissionsParser());
52146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!permissions_parser_->Parse(this, error))
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (manifest_->HasKey(keys::kConvertedFromUserScript)) {
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    manifest_->GetBoolean(keys::kConvertedFromUserScript,
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          &converted_from_user_script_);
52790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
52890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
52990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!LoadSharedFeatures(error))
53090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  permissions_parser_->Finalize(this);
53346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  permissions_parser_.reset();
53446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  finished_parsing_manifest_ = true;
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
53746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  permissions_data_.reset(new PermissionsData(this));
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Extension::LoadRequiredFeatures(base::string16* error) {
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!LoadName(error) ||
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !LoadVersion(error))
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Extension::LoadName(base::string16* error) {
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 localized_name;
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!manifest_->GetString(keys::kName, &localized_name)) {
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error = base::ASCIIToUTF16(errors::kInvalidName);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  non_localized_name_ = base::UTF16ToUTF8(localized_name);
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::i18n::AdjustStringForLocaleDirection(&localized_name);
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  name_ = base::UTF16ToUTF8(localized_name);
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Extension::LoadVersion(base::string16* error) {
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string version_str;
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!manifest_->GetString(keys::kVersion, &version_str)) {
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error = base::ASCIIToUTF16(errors::kInvalidVersion);
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  version_.reset(new Version(version_str));
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!version_->IsValid() || version_->components().size() > 4) {
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error = base::ASCIIToUTF16(errors::kInvalidVersion);
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Extension::LoadAppFeatures(base::string16* error) {
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!LoadExtent(keys::kWebURLs, &extent_,
577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                  errors::kInvalidWebURLs, errors::kInvalidWebURL, error)) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (manifest_->HasKey(keys::kDisplayInLauncher) &&
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !manifest_->GetBoolean(keys::kDisplayInLauncher, &display_in_launcher_)) {
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error = base::ASCIIToUTF16(errors::kInvalidDisplayInLauncher);
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (manifest_->HasKey(keys::kDisplayInNewTabPage)) {
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!manifest_->GetBoolean(keys::kDisplayInNewTabPage,
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               &display_in_new_tab_page_)) {
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error = base::ASCIIToUTF16(errors::kInvalidDisplayInNewTabPage);
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Inherit default from display_in_launcher property.
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    display_in_new_tab_page_ = display_in_launcher_;
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Extension::LoadExtent(const char* key,
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           URLPatternSet* extent,
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const char* list_error,
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const char* value_error,
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           base::string16* error) {
6037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const base::Value* temp_pattern_value = NULL;
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!manifest_->Get(key, &temp_pattern_value))
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const base::ListValue* pattern_list = NULL;
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!temp_pattern_value->GetAsList(&pattern_list)) {
6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error = base::ASCIIToUTF16(list_error);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < pattern_list->GetSize(); ++i) {
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string pattern_string;
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!pattern_list->GetString(i, &pattern_string)) {
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *error = ErrorUtils::FormatErrorMessageUTF16(value_error,
617b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                                   base::UintToString(i),
618b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                                   errors::kExpectString);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    URLPattern pattern(kValidWebExtentSchemes);
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    URLPattern::ParseResult parse_result = pattern.Parse(pattern_string);
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (parse_result == URLPattern::PARSE_ERROR_EMPTY_PATH) {
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pattern_string += "/";
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      parse_result = pattern.Parse(pattern_string);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (parse_result != URLPattern::PARSE_SUCCESS) {
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *error = ErrorUtils::FormatErrorMessageUTF16(
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          value_error,
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::UintToString(i),
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          URLPattern::GetParseResultString(parse_result));
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Do not allow authors to claim "<all_urls>".
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (pattern.match_all_urls()) {
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *error = ErrorUtils::FormatErrorMessageUTF16(
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          value_error,
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::UintToString(i),
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          errors::kCannotClaimAllURLsInExtent);
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Do not allow authors to claim "*" for host.
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (pattern.host().empty()) {
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *error = ErrorUtils::FormatErrorMessageUTF16(
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          value_error,
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::UintToString(i),
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          errors::kCannotClaimAllHostsInExtent);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We do not allow authors to put wildcards in their paths. Instead, we
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // imply one at the end.
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (pattern.path().find('*') != std::string::npos) {
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *error = ErrorUtils::FormatErrorMessageUTF16(
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          value_error,
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::UintToString(i),
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          errors::kNoWildCardsInPaths);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pattern.SetPath(pattern.path() + '*');
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    extent->AddPattern(pattern);
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Extension::LoadSharedFeatures(base::string16* error) {
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!LoadDescription(error) ||
674424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      !ManifestHandler::ParseExtension(this, error) ||
675424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      !LoadShortName(error))
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Extension::LoadDescription(base::string16* error) {
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (manifest_->HasKey(keys::kDescription) &&
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !manifest_->GetString(keys::kDescription, &description_)) {
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error = base::ASCIIToUTF16(errors::kInvalidDescription);
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Extension::LoadManifestVersion(base::string16* error) {
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Get the original value out of the dictionary so that we can validate it
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // more strictly.
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (manifest_->value()->HasKey(keys::kManifestVersion)) {
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int manifest_version = 1;
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!manifest_->GetInteger(keys::kManifestVersion, &manifest_version) ||
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        manifest_version < 1) {
6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error = base::ASCIIToUTF16(errors::kInvalidManifestVersion);
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manifest_version_ = manifest_->GetManifestVersion();
7033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (manifest_version_ < kModernManifestVersion &&
7043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ((creation_flags_ & REQUIRE_MODERN_MANIFEST_VERSION &&
7053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        !CommandLine::ForCurrentProcess()->HasSwitch(
7063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            switches::kAllowLegacyExtensionManifests)) ||
7073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       GetType() == Manifest::TYPE_PLATFORM_APP)) {
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *error = ErrorUtils::FormatErrorMessageUTF16(
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        errors::kInvalidManifestVersionOld,
7103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::IntToString(kModernManifestVersion),
7113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        is_platform_app() ? "apps" : "extensions");
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Extension::LoadShortName(base::string16* error) {
719424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (manifest_->HasKey(keys::kShortName)) {
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 localized_short_name;
721424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!manifest_->GetString(keys::kShortName, &localized_short_name) ||
722424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        localized_short_name.empty()) {
7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error = base::ASCIIToUTF16(errors::kInvalidShortName);
724424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return false;
725424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
726424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
727424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    base::i18n::AdjustStringForLocaleDirection(&localized_short_name);
7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    short_name_ = base::UTF16ToUTF8(localized_short_name);
729424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  } else {
730424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    short_name_ = name_;
731424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
732424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return true;
733424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
734424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
7357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)ExtensionInfo::ExtensionInfo(const base::DictionaryValue* manifest,
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& id,
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const base::FilePath& path,
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             Manifest::Location location)
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : extension_id(id),
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_path(path),
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_location(location) {
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (manifest)
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    extension_manifest.reset(manifest->DeepCopy());
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionInfo::~ExtensionInfo() {}
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)InstalledExtensionInfo::InstalledExtensionInfo(
749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Extension* extension,
75090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    bool is_update,
751cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool from_ephemeral,
75290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::string& old_name)
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : extension(extension),
75490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      is_update(is_update),
755cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      from_ephemeral(from_ephemeral),
75690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      old_name(old_name) {}
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UnloadedExtensionInfo::UnloadedExtensionInfo(
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Extension* extension,
7601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    UnloadedExtensionInfo::Reason reason)
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : reason(reason),
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extension(extension) {}
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo(
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Extension* extension,
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PermissionSet* permissions,
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Reason reason)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : reason(reason),
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension(extension),
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      permissions(permissions) {}
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}   // namespace extensions
773