1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/shared_module_info.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/lazy_instance.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/version.h"
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/crx_file/id_util.h"
14a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "extensions/common/constants.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "extensions/common/error_utils.h"
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h"
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "extensions/common/permissions/permission_set.h"
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace extensions {
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace keys = manifest_keys;
23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace values = manifest_values;
24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace errors = manifest_errors;
25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kSharedModule[] = "shared_module";
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static base::LazyInstance<SharedModuleInfo> g_empty_shared_module_info =
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LAZY_INSTANCE_INITIALIZER;
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const SharedModuleInfo& GetSharedModuleInfo(const Extension* extension) {
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SharedModuleInfo* info = static_cast<SharedModuleInfo*>(
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extension->GetManifestData(kSharedModule));
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!info)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return g_empty_shared_module_info.Get();
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return *info;
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SharedModuleInfo::SharedModuleInfo() {
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SharedModuleInfo::~SharedModuleInfo() {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SharedModuleInfo::ParseImportedPath(const std::string& path,
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         std::string* import_id,
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         std::string* import_relative_path) {
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<std::string> tokens;
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Tokenize(path, std::string("/"), &tokens);
55a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (tokens.size() > 2 && tokens[0] == kModulesDir &&
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      crx_file::id_util::IdIsValid(tokens[1])) {
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *import_id = tokens[1];
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *import_relative_path = tokens[2];
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (size_t i = 3; i < tokens.size(); ++i)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *import_relative_path += "/" + tokens[i];
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SharedModuleInfo::IsImportedPath(const std::string& path) {
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<std::string> tokens;
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Tokenize(path, std::string("/"), &tokens);
68a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  if (tokens.size() > 2 && tokens[0] == kModulesDir &&
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      crx_file::id_util::IdIsValid(tokens[1])) {
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SharedModuleInfo::IsSharedModule(const Extension* extension) {
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(extension);
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return extension->manifest()->is_shared_module();
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SharedModuleInfo::IsExportAllowed(const Extension* extension,
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       const std::string& relative_path) {
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetSharedModuleInfo(extension).
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      exported_set_.MatchesURL(extension->url().Resolve(relative_path));
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool SharedModuleInfo::IsExportAllowedByWhitelist(const Extension* extension,
90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                  const std::string& other_id) {
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Sanity check. In case the caller did not check |extension| to make sure it
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // is a shared module, we do not want it to appear that the extension with
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // |other_id| importing |extension| is valid.
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!SharedModuleInfo::IsSharedModule(extension))
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const SharedModuleInfo& info = GetSharedModuleInfo(extension);
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (info.export_whitelist_.empty())
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return true;
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (info.export_whitelist_.find(other_id) != info.export_whitelist_.end())
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return true;
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return false;
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SharedModuleInfo::ImportsExtensionById(const Extension* extension,
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            const std::string& other_id) {
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const SharedModuleInfo& info = GetSharedModuleInfo(extension);
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < info.imports_.size(); i++) {
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (info.imports_[i].extension_id == other_id)
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return true;
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SharedModuleInfo::ImportsModules(const Extension* extension) {
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetSharedModuleInfo(extension).imports_.size() > 0;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::vector<SharedModuleInfo::ImportInfo>& SharedModuleInfo::GetImports(
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Extension* extension) {
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetSharedModuleInfo(extension).imports_;
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SharedModuleInfo::Parse(const Extension* extension,
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             base::string16* error) {
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool has_import = extension->manifest()->HasKey(keys::kImport);
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool has_export = extension->manifest()->HasKey(keys::kExport);
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!has_import && !has_export)
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (has_import && has_export) {
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error = base::ASCIIToUTF16(errors::kInvalidImportAndExport);
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (has_export) {
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const base::DictionaryValue* export_value = NULL;
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!extension->manifest()->GetDictionary(keys::kExport, &export_value)) {
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error = base::ASCIIToUTF16(errors::kInvalidExport);
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const base::ListValue* resources_list = NULL;
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!export_value->GetList(keys::kResources, &resources_list)) {
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error = base::ASCIIToUTF16(errors::kInvalidExportResources);
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (export_value->HasKey(keys::kWhitelist)) {
150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      const base::ListValue* whitelist = NULL;
151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if (!export_value->GetList(keys::kWhitelist, &whitelist)) {
152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        *error = base::ASCIIToUTF16(errors::kInvalidExportWhitelist);
153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        return false;
154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      }
155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      for (size_t i = 0; i < whitelist->GetSize(); ++i) {
156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        std::string extension_id;
157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        if (!whitelist->GetString(i, &extension_id) ||
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            !crx_file::id_util::IdIsValid(extension_id)) {
159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          *error = ErrorUtils::FormatErrorMessageUTF16(
160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              errors::kInvalidExportWhitelistString, base::IntToString(i));
161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          return false;
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        }
163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        export_whitelist_.insert(extension_id);
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      }
165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (size_t i = 0; i < resources_list->GetSize(); ++i) {
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string resource_path;
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!resources_list->GetString(i, &resource_path)) {
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        *error = ErrorUtils::FormatErrorMessageUTF16(
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            errors::kInvalidExportResourcesString, base::IntToString(i));
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return false;
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const GURL& resolved_path = extension->url().Resolve(resource_path);
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!resolved_path.is_valid()) {
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        *error = ErrorUtils::FormatErrorMessageUTF16(
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            errors::kInvalidExportResourcesString, base::IntToString(i));
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return false;
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      exported_set_.AddPattern(
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          URLPattern(URLPattern::SCHEME_EXTENSION, resolved_path.spec()));
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (has_import) {
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const base::ListValue* import_list = NULL;
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!extension->manifest()->GetList(keys::kImport, &import_list)) {
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *error = base::ASCIIToUTF16(errors::kInvalidImport);
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (size_t i = 0; i < import_list->GetSize(); ++i) {
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const base::DictionaryValue* import_entry = NULL;
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!import_list->GetDictionary(i, &import_entry)) {
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        *error = base::ASCIIToUTF16(errors::kInvalidImport);
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return false;
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string extension_id;
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      imports_.push_back(ImportInfo());
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!import_entry->GetString(keys::kId, &extension_id) ||
19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          !crx_file::id_util::IdIsValid(extension_id)) {
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        *error = ErrorUtils::FormatErrorMessageUTF16(
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            errors::kInvalidImportId, base::IntToString(i));
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return false;
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      imports_.back().extension_id = extension_id;
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (import_entry->HasKey(keys::kMinimumVersion)) {
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string min_version;
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (!import_entry->GetString(keys::kMinimumVersion, &min_version)) {
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          *error = ErrorUtils::FormatErrorMessageUTF16(
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              errors::kInvalidImportVersion, base::IntToString(i));
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return false;
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        imports_.back().minimum_version = min_version;
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        Version v(min_version);
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (!v.IsValid()) {
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          *error = ErrorUtils::FormatErrorMessageUTF16(
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              errors::kInvalidImportVersion, base::IntToString(i));
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return false;
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SharedModuleHandler::SharedModuleHandler() {
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SharedModuleHandler::~SharedModuleHandler() {
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SharedModuleHandler::Parse(Extension* extension, base::string16* error) {
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SharedModuleInfo> info(new SharedModuleInfo);
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!info->Parse(extension, error))
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  extension->SetManifestData(kSharedModule, info.release());
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SharedModuleHandler::Validate(
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const Extension* extension,
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string* error,
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<InstallWarning>* warnings) const {
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Extensions that export resources should not have any permissions of their
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // own, instead they rely on the permissions of the extensions which import
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // them.
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (SharedModuleInfo::IsSharedModule(extension) &&
24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      !extension->permissions_data()->active_permissions()->IsEmpty()) {
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *error = errors::kInvalidExportPermissions;
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::vector<std::string> SharedModuleHandler::Keys() const {
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const char* keys[] = {
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    keys::kExport,
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    keys::kImport
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return std::vector<std::string>(keys, keys + arraysize(keys));
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
263a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}  // namespace extensions
264