Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / extensions / common / manifest_handlers / file_handler_info.cc
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.
4
5 #include "extensions/common/manifest_handlers/file_handler_info.h"
6
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"
15
16 namespace extensions {
17
18 namespace keys = manifest_keys;
19 namespace errors = manifest_errors;
20
21 namespace {
22 const int kMaxTypeAndExtensionHandlers = 200;
23 const char kNotRecognized[] = "'%s' is not a recognized file handler property.";
24 }
25
26 FileHandlerInfo::FileHandlerInfo() {}
27 FileHandlerInfo::~FileHandlerInfo() {}
28
29 FileHandlers::FileHandlers() {}
30 FileHandlers::~FileHandlers() {}
31
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;
38 }
39
40 FileHandlersParser::FileHandlersParser() {
41 }
42
43 FileHandlersParser::~FileHandlersParser() {
44 }
45
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;
53
54   handler.id = handler_id;
55
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;
62   }
63
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;
70   }
71
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;
78   }
79
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;
89       }
90       handler.types.insert(type);
91     }
92   }
93
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;
103       }
104       handler.extensions.insert(file_extension);
105     }
106   }
107
108   file_handlers->push_back(handler);
109
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()));
119     }
120   }
121
122   return true;
123 }
124
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;
132   }
133
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;
149     }
150   }
151
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();
158   }
159
160   if (filter_count > kMaxTypeAndExtensionHandlers) {
161     *error = base::ASCIIToUTF16(
162         errors::kInvalidFileHandlersTooManyTypesAndExtensions);
163     return false;
164   }
165
166   extension->SetManifestData(keys::kFileHandlers, info.release());
167   extension->AddInstallWarnings(install_warnings);
168   return true;
169 }
170
171 const std::vector<std::string> FileHandlersParser::Keys() const {
172   return SingleKey(keys::kFileHandlers);
173 }
174
175 }  // namespace extensions