1 // Copyright (c) 2012 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 "chrome/common/extensions/api/file_handlers/file_handlers_parser.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "base/values.h" 11 #include "chrome/common/extensions/extension_manifest_constants.h" 12 #include "chrome/common/extensions/manifest.h" 13 #include "extensions/common/error_utils.h" 14 15 namespace keys = extension_manifest_keys; 16 17 namespace extensions { 18 19 FileHandlerInfo::FileHandlerInfo() {} 20 FileHandlerInfo::~FileHandlerInfo() {} 21 22 FileHandlers::FileHandlers() {} 23 FileHandlers::~FileHandlers() {} 24 25 // static 26 const std::vector<FileHandlerInfo>* FileHandlers::GetFileHandlers( 27 const Extension* extension) { 28 FileHandlers* info = static_cast<FileHandlers*>( 29 extension->GetManifestData(extension_manifest_keys::kFileHandlers)); 30 return info ? &info->file_handlers : NULL; 31 } 32 33 FileHandlersParser::FileHandlersParser() { 34 } 35 36 FileHandlersParser::~FileHandlersParser() { 37 } 38 39 bool LoadFileHandler(const std::string& handler_id, 40 const base::DictionaryValue& handler_info, 41 std::vector<FileHandlerInfo>* file_handlers, 42 string16* error) { 43 DCHECK(error); 44 FileHandlerInfo handler; 45 46 handler.id = handler_id; 47 48 const base::ListValue* mime_types = NULL; 49 if (handler_info.HasKey(keys::kFileHandlerTypes) && 50 !handler_info.GetList(keys::kFileHandlerTypes, &mime_types)) { 51 *error = ErrorUtils::FormatErrorMessageUTF16( 52 extension_manifest_errors::kInvalidFileHandlerType, handler_id); 53 return false; 54 } 55 56 const base::ListValue* file_extensions = NULL; 57 if (handler_info.HasKey(keys::kFileHandlerExtensions) && 58 !handler_info.GetList(keys::kFileHandlerExtensions, &file_extensions)) { 59 *error = ErrorUtils::FormatErrorMessageUTF16( 60 extension_manifest_errors::kInvalidFileHandlerExtension, handler_id); 61 return false; 62 } 63 64 if ((!mime_types || mime_types->GetSize() == 0) && 65 (!file_extensions || file_extensions->GetSize() == 0)) { 66 *error = ErrorUtils::FormatErrorMessageUTF16( 67 extension_manifest_errors::kInvalidFileHandlerNoTypeOrExtension, 68 handler_id); 69 return false; 70 } 71 72 if (handler_info.HasKey(keys::kFileHandlerTitle) && 73 !handler_info.GetString(keys::kFileHandlerTitle, &handler.title)) { 74 *error = ASCIIToUTF16(extension_manifest_errors::kInvalidFileHandlerTitle); 75 return false; 76 } 77 78 if (mime_types) { 79 std::string type; 80 for (size_t i = 0; i < mime_types->GetSize(); ++i) { 81 if (!mime_types->GetString(i, &type)) { 82 *error = ErrorUtils::FormatErrorMessageUTF16( 83 extension_manifest_errors::kInvalidFileHandlerTypeElement, 84 handler_id, 85 std::string(base::IntToString(i))); 86 return false; 87 } 88 handler.types.insert(type); 89 } 90 } 91 92 if (file_extensions) { 93 std::string file_extension; 94 for (size_t i = 0; i < file_extensions->GetSize(); ++i) { 95 if (!file_extensions->GetString(i, &file_extension)) { 96 *error = ErrorUtils::FormatErrorMessageUTF16( 97 extension_manifest_errors::kInvalidFileHandlerExtensionElement, 98 handler_id, 99 std::string(base::IntToString(i))); 100 return false; 101 } 102 handler.extensions.insert(file_extension); 103 } 104 } 105 106 file_handlers->push_back(handler); 107 return true; 108 } 109 110 bool FileHandlersParser::Parse(Extension* extension, string16* error) { 111 scoped_ptr<FileHandlers> info(new FileHandlers); 112 const base::DictionaryValue* all_handlers = NULL; 113 if (!extension->manifest()->GetDictionary(keys::kFileHandlers, 114 &all_handlers)) { 115 *error = ASCIIToUTF16(extension_manifest_errors::kInvalidFileHandlers); 116 return false; 117 } 118 119 DCHECK(extension->is_platform_app()); 120 121 for (base::DictionaryValue::Iterator iter(*all_handlers); !iter.IsAtEnd(); 122 iter.Advance()) { 123 // A file handler entry is a title and a list of MIME types to handle. 124 const base::DictionaryValue* handler = NULL; 125 if (iter.value().GetAsDictionary(&handler)) { 126 if (!LoadFileHandler(iter.key(), *handler, &info->file_handlers, error)) 127 return false; 128 } else { 129 *error = ASCIIToUTF16(extension_manifest_errors::kInvalidFileHandlers); 130 return false; 131 } 132 } 133 134 extension->SetManifestData(keys::kFileHandlers, info.release()); 135 return true; 136 } 137 138 const std::vector<std::string> FileHandlersParser::Keys() const { 139 return SingleKey(keys::kFileHandlers); 140 } 141 142 } // namespace extensions 143