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
;
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() {}
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
) {
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
);
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
);
72 if ((!mime_types
|| mime_types
->empty()) &&
73 (!file_extensions
|| file_extensions
->empty())) {
74 *error
= ErrorUtils::FormatErrorMessageUTF16(
75 errors::kInvalidFileHandlerNoTypeOrExtension
,
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
,
87 std::string(base::IntToString(i
)));
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
,
101 std::string(base::IntToString(i
)));
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();
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()),
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
,
130 *error
= base::ASCIIToUTF16(errors::kInvalidFileHandlers
);
134 std::vector
<InstallWarning
> install_warnings
;
135 for (base::DictionaryValue::Iterator
iter(*all_handlers
);
138 const base::DictionaryValue
* handler
= NULL
;
139 if (iter
.value().GetAsDictionary(&handler
)) {
140 if (!LoadFileHandler(iter
.key(),
142 &info
->file_handlers
,
147 *error
= base::ASCIIToUTF16(errors::kInvalidFileHandlers
);
152 int filter_count
= 0;
153 for (FileHandlersInfo::const_iterator iter
= info
->file_handlers
.begin();
154 iter
!= info
->file_handlers
.end();
156 filter_count
+= iter
->types
.size();
157 filter_count
+= iter
->extensions
.size();
160 if (filter_count
> kMaxTypeAndExtensionHandlers
) {
161 *error
= base::ASCIIToUTF16(
162 errors::kInvalidFileHandlersTooManyTypesAndExtensions
);
166 extension
->SetManifestData(keys::kFileHandlers
, info
.release());
167 extension
->AddInstallWarnings(install_warnings
);
171 const std::vector
<std::string
> FileHandlersParser::Keys() const {
172 return SingleKey(keys::kFileHandlers
);
175 } // namespace extensions