Adding Peter Thatcher to the owners file.
[chromium-blink-merge.git] / extensions / common / manifest_handlers / file_handler_info.cc
blob1323252cab9a385404f60689b24ab0fa405eff56
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/common/manifest_handlers/file_handler_info.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "extensions/common/error_utils.h"
13 #include "extensions/common/manifest.h"
14 #include "extensions/common/manifest_constants.h"
16 namespace extensions {
18 namespace keys = manifest_keys;
19 namespace errors = manifest_errors;
21 namespace {
22 const int kMaxTypeAndExtensionHandlers = 200;
23 const char kNotRecognized[] = "'%s' is not a recognized file handler property.";
26 FileHandlerInfo::FileHandlerInfo() {}
27 FileHandlerInfo::~FileHandlerInfo() {}
29 FileHandlers::FileHandlers() {}
30 FileHandlers::~FileHandlers() {}
32 // static
33 const FileHandlersInfo* FileHandlers::GetFileHandlers(
34 const Extension* extension) {
35 FileHandlers* info = static_cast<FileHandlers*>(
36 extension->GetManifestData(keys::kFileHandlers));
37 return info ? &info->file_handlers : NULL;
40 FileHandlersParser::FileHandlersParser() {
43 FileHandlersParser::~FileHandlersParser() {
46 bool LoadFileHandler(const std::string& handler_id,
47 const base::DictionaryValue& handler_info,
48 FileHandlersInfo* file_handlers,
49 base::string16* error,
50 std::vector<InstallWarning>* install_warnings) {
51 DCHECK(error);
52 FileHandlerInfo handler;
54 handler.id = handler_id;
56 const base::ListValue* mime_types = NULL;
57 if (handler_info.HasKey(keys::kFileHandlerTypes) &&
58 !handler_info.GetList(keys::kFileHandlerTypes, &mime_types)) {
59 *error = ErrorUtils::FormatErrorMessageUTF16(
60 errors::kInvalidFileHandlerType, handler_id);
61 return false;
64 const base::ListValue* file_extensions = NULL;
65 if (handler_info.HasKey(keys::kFileHandlerExtensions) &&
66 !handler_info.GetList(keys::kFileHandlerExtensions, &file_extensions)) {
67 *error = ErrorUtils::FormatErrorMessageUTF16(
68 errors::kInvalidFileHandlerExtension, handler_id);
69 return false;
72 if ((!mime_types || mime_types->empty()) &&
73 (!file_extensions || file_extensions->empty())) {
74 *error = ErrorUtils::FormatErrorMessageUTF16(
75 errors::kInvalidFileHandlerNoTypeOrExtension,
76 handler_id);
77 return false;
80 if (mime_types) {
81 std::string type;
82 for (size_t i = 0; i < mime_types->GetSize(); ++i) {
83 if (!mime_types->GetString(i, &type)) {
84 *error = ErrorUtils::FormatErrorMessageUTF16(
85 errors::kInvalidFileHandlerTypeElement,
86 handler_id,
87 std::string(base::IntToString(i)));
88 return false;
90 handler.types.insert(type);
94 if (file_extensions) {
95 std::string file_extension;
96 for (size_t i = 0; i < file_extensions->GetSize(); ++i) {
97 if (!file_extensions->GetString(i, &file_extension)) {
98 *error = ErrorUtils::FormatErrorMessageUTF16(
99 errors::kInvalidFileHandlerExtensionElement,
100 handler_id,
101 std::string(base::IntToString(i)));
102 return false;
104 handler.extensions.insert(file_extension);
108 file_handlers->push_back(handler);
110 // Check for unknown keys.
111 for (base::DictionaryValue::Iterator it(handler_info); !it.IsAtEnd();
112 it.Advance()) {
113 if (it.key() != keys::kFileHandlerExtensions &&
114 it.key() != keys::kFileHandlerTypes) {
115 install_warnings->push_back(
116 InstallWarning(base::StringPrintf(kNotRecognized, it.key().c_str()),
117 keys::kFileHandlers,
118 it.key()));
122 return true;
125 bool FileHandlersParser::Parse(Extension* extension, base::string16* error) {
126 scoped_ptr<FileHandlers> info(new FileHandlers);
127 const base::DictionaryValue* all_handlers = NULL;
128 if (!extension->manifest()->GetDictionary(keys::kFileHandlers,
129 &all_handlers)) {
130 *error = base::ASCIIToUTF16(errors::kInvalidFileHandlers);
131 return false;
134 std::vector<InstallWarning> install_warnings;
135 for (base::DictionaryValue::Iterator iter(*all_handlers);
136 !iter.IsAtEnd();
137 iter.Advance()) {
138 const base::DictionaryValue* handler = NULL;
139 if (iter.value().GetAsDictionary(&handler)) {
140 if (!LoadFileHandler(iter.key(),
141 *handler,
142 &info->file_handlers,
143 error,
144 &install_warnings))
145 return false;
146 } else {
147 *error = base::ASCIIToUTF16(errors::kInvalidFileHandlers);
148 return false;
152 int filter_count = 0;
153 for (FileHandlersInfo::const_iterator iter = info->file_handlers.begin();
154 iter != info->file_handlers.end();
155 iter++) {
156 filter_count += iter->types.size();
157 filter_count += iter->extensions.size();
160 if (filter_count > kMaxTypeAndExtensionHandlers) {
161 *error = base::ASCIIToUTF16(
162 errors::kInvalidFileHandlersTooManyTypesAndExtensions);
163 return false;
166 extension->SetManifestData(keys::kFileHandlers, info.release());
167 extension->AddInstallWarnings(install_warnings);
168 return true;
171 const std::vector<std::string> FileHandlersParser::Keys() const {
172 return SingleKey(keys::kFileHandlers);
175 } // namespace extensions