Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(578)

Side by Side Diff: chrome/common/extensions/unpacker.cc

Issue 10704060: Move ExtensionUnpacker into extensions:: namespace, rename it to Unpacker (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Even later master Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/common/extensions/unpacker.h ('k') | chrome/common/extensions/unpacker_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/extensions/extension_unpacker.h" 5 #include "chrome/common/extensions/unpacker.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/json/json_file_value_serializer.h" 10 #include "base/json/json_file_value_serializer.h"
11 #include "base/memory/scoped_handle.h" 11 #include "base/memory/scoped_handle.h"
12 #include "base/scoped_temp_dir.h" 12 #include "base/scoped_temp_dir.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/threading/thread.h" 14 #include "base/threading/thread.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "base/values.h" 16 #include "base/values.h"
17 #include "chrome/common/extensions/extension.h" 17 #include "chrome/common/extensions/extension.h"
18 #include "chrome/common/extensions/extension_manifest_constants.h" 18 #include "chrome/common/extensions/extension_manifest_constants.h"
19 #include "chrome/common/extensions/extension_file_util.h" 19 #include "chrome/common/extensions/extension_file_util.h"
20 #include "chrome/common/extensions/extension_l10n_util.h" 20 #include "chrome/common/extensions/extension_l10n_util.h"
21 #include "chrome/common/url_constants.h" 21 #include "chrome/common/url_constants.h"
22 #include "chrome/common/zip.h" 22 #include "chrome/common/zip.h"
23 #include "content/public/common/common_param_traits.h" 23 #include "content/public/common/common_param_traits.h"
24 #include "ipc/ipc_message_utils.h" 24 #include "ipc/ipc_message_utils.h"
25 #include "net/base/file_stream.h" 25 #include "net/base/file_stream.h"
26 #include "third_party/skia/include/core/SkBitmap.h" 26 #include "third_party/skia/include/core/SkBitmap.h"
27 #include "webkit/glue/image_decoder.h" 27 #include "webkit/glue/image_decoder.h"
28 28
29 namespace errors = extension_manifest_errors; 29 namespace errors = extension_manifest_errors;
30 namespace keys = extension_manifest_keys; 30 namespace keys = extension_manifest_keys;
31 namespace filenames = extension_filenames; 31 namespace filenames = extension_filenames;
32 32
33 using extensions::Extension;
34
35 namespace { 33 namespace {
36 34
37 // Errors 35 // Errors
38 const char* kCouldNotCreateDirectoryError = 36 const char* kCouldNotCreateDirectoryError =
39 "Could not create directory for unzipping: "; 37 "Could not create directory for unzipping: ";
40 const char* kCouldNotDecodeImageError = "Could not decode theme image."; 38 const char* kCouldNotDecodeImageError = "Could not decode theme image.";
41 const char* kCouldNotUnzipExtension = "Could not unzip extension."; 39 const char* kCouldNotUnzipExtension = "Could not unzip extension.";
42 const char* kPathNamesMustBeAbsoluteOrLocalError = 40 const char* kPathNamesMustBeAbsoluteOrLocalError =
43 "Path names must not be absolute or contain '..'."; 41 "Path names must not be absolute or contain '..'.";
44 42
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 } 77 }
80 ++i; 78 ++i;
81 } 79 }
82 } 80 }
83 81
84 return false; 82 return false;
85 } 83 }
86 84
87 } // namespace 85 } // namespace
88 86
89 ExtensionUnpacker::ExtensionUnpacker(const FilePath& extension_path, 87 namespace extensions {
90 const std::string& extension_id, 88
91 Extension::Location location, 89 Unpacker::Unpacker(const FilePath& extension_path,
92 int creation_flags) 90 const std::string& extension_id,
91 Extension::Location location,
92 int creation_flags)
93 : extension_path_(extension_path), 93 : extension_path_(extension_path),
94 extension_id_(extension_id), 94 extension_id_(extension_id),
95 location_(location), 95 location_(location),
96 creation_flags_(creation_flags) { 96 creation_flags_(creation_flags) {
97 } 97 }
98 98
99 ExtensionUnpacker::~ExtensionUnpacker() { 99 Unpacker::~Unpacker() {
100 } 100 }
101 101
102 DictionaryValue* ExtensionUnpacker::ReadManifest() { 102 DictionaryValue* Unpacker::ReadManifest() {
103 FilePath manifest_path = 103 FilePath manifest_path =
104 temp_install_dir_.Append(Extension::kManifestFilename); 104 temp_install_dir_.Append(Extension::kManifestFilename);
105 if (!file_util::PathExists(manifest_path)) { 105 if (!file_util::PathExists(manifest_path)) {
106 SetError(errors::kInvalidManifest); 106 SetError(errors::kInvalidManifest);
107 return NULL; 107 return NULL;
108 } 108 }
109 109
110 JSONFileValueSerializer serializer(manifest_path); 110 JSONFileValueSerializer serializer(manifest_path);
111 std::string error; 111 std::string error;
112 scoped_ptr<Value> root(serializer.Deserialize(NULL, &error)); 112 scoped_ptr<Value> root(serializer.Deserialize(NULL, &error));
113 if (!root.get()) { 113 if (!root.get()) {
114 SetError(error); 114 SetError(error);
115 return NULL; 115 return NULL;
116 } 116 }
117 117
118 if (!root->IsType(Value::TYPE_DICTIONARY)) { 118 if (!root->IsType(Value::TYPE_DICTIONARY)) {
119 SetError(errors::kInvalidManifest); 119 SetError(errors::kInvalidManifest);
120 return NULL; 120 return NULL;
121 } 121 }
122 122
123 return static_cast<DictionaryValue*>(root.release()); 123 return static_cast<DictionaryValue*>(root.release());
124 } 124 }
125 125
126 bool ExtensionUnpacker::ReadAllMessageCatalogs( 126 bool Unpacker::ReadAllMessageCatalogs(const std::string& default_locale) {
127 const std::string& default_locale) {
128 FilePath locales_path = 127 FilePath locales_path =
129 temp_install_dir_.Append(Extension::kLocaleFolder); 128 temp_install_dir_.Append(Extension::kLocaleFolder);
130 129
131 // Not all folders under _locales have to be valid locales. 130 // Not all folders under _locales have to be valid locales.
132 file_util::FileEnumerator locales(locales_path, 131 file_util::FileEnumerator locales(locales_path,
133 false, 132 false,
134 file_util::FileEnumerator::DIRECTORIES); 133 file_util::FileEnumerator::DIRECTORIES);
135 134
136 std::set<std::string> all_locales; 135 std::set<std::string> all_locales;
137 extension_l10n_util::GetAllLocales(&all_locales); 136 extension_l10n_util::GetAllLocales(&all_locales);
138 FilePath locale_path; 137 FilePath locale_path;
139 while (!(locale_path = locales.Next()).empty()) { 138 while (!(locale_path = locales.Next()).empty()) {
140 if (extension_l10n_util::ShouldSkipValidation(locales_path, locale_path, 139 if (extension_l10n_util::ShouldSkipValidation(locales_path, locale_path,
141 all_locales)) 140 all_locales))
142 continue; 141 continue;
143 142
144 FilePath messages_path = 143 FilePath messages_path =
145 locale_path.Append(Extension::kMessagesFilename); 144 locale_path.Append(Extension::kMessagesFilename);
146 145
147 if (!ReadMessageCatalog(messages_path)) 146 if (!ReadMessageCatalog(messages_path))
148 return false; 147 return false;
149 } 148 }
150 149
151 return true; 150 return true;
152 } 151 }
153 152
154 bool ExtensionUnpacker::Run() { 153 bool Unpacker::Run() {
155 DVLOG(1) << "Installing extension " << extension_path_.value(); 154 DVLOG(1) << "Installing extension " << extension_path_.value();
156 155
157 // <profile>/Extensions/INSTALL_TEMP/<version> 156 // <profile>/Extensions/INSTALL_TEMP/<version>
158 temp_install_dir_ = 157 temp_install_dir_ =
159 extension_path_.DirName().AppendASCII(filenames::kTempExtensionName); 158 extension_path_.DirName().AppendASCII(filenames::kTempExtensionName);
160 159
161 if (!file_util::CreateDirectory(temp_install_dir_)) { 160 if (!file_util::CreateDirectory(temp_install_dir_)) {
162 #if defined(OS_WIN) 161 #if defined(OS_WIN)
163 std::string dir_string = WideToUTF8(temp_install_dir_.value()); 162 std::string dir_string = WideToUTF8(temp_install_dir_.value());
164 #else 163 #else
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 // Parse all message catalogs (if any). 210 // Parse all message catalogs (if any).
212 parsed_catalogs_.reset(new DictionaryValue); 211 parsed_catalogs_.reset(new DictionaryValue);
213 if (!extension->default_locale().empty()) { 212 if (!extension->default_locale().empty()) {
214 if (!ReadAllMessageCatalogs(extension->default_locale())) 213 if (!ReadAllMessageCatalogs(extension->default_locale()))
215 return false; // Error was already reported. 214 return false; // Error was already reported.
216 } 215 }
217 216
218 return true; 217 return true;
219 } 218 }
220 219
221 bool ExtensionUnpacker::DumpImagesToFile() { 220 bool Unpacker::DumpImagesToFile() {
222 IPC::Message pickle; // We use a Message so we can use WriteParam. 221 IPC::Message pickle; // We use a Message so we can use WriteParam.
223 IPC::WriteParam(&pickle, decoded_images_); 222 IPC::WriteParam(&pickle, decoded_images_);
224 223
225 FilePath path = extension_path_.DirName().AppendASCII( 224 FilePath path = extension_path_.DirName().AppendASCII(
226 filenames::kDecodedImagesFilename); 225 filenames::kDecodedImagesFilename);
227 if (!file_util::WriteFile(path, static_cast<const char*>(pickle.data()), 226 if (!file_util::WriteFile(path, static_cast<const char*>(pickle.data()),
228 pickle.size())) { 227 pickle.size())) {
229 SetError("Could not write image data to disk."); 228 SetError("Could not write image data to disk.");
230 return false; 229 return false;
231 } 230 }
232 231
233 return true; 232 return true;
234 } 233 }
235 234
236 bool ExtensionUnpacker::DumpMessageCatalogsToFile() { 235 bool Unpacker::DumpMessageCatalogsToFile() {
237 IPC::Message pickle; 236 IPC::Message pickle;
238 IPC::WriteParam(&pickle, *parsed_catalogs_.get()); 237 IPC::WriteParam(&pickle, *parsed_catalogs_.get());
239 238
240 FilePath path = extension_path_.DirName().AppendASCII( 239 FilePath path = extension_path_.DirName().AppendASCII(
241 filenames::kDecodedMessageCatalogsFilename); 240 filenames::kDecodedMessageCatalogsFilename);
242 if (!file_util::WriteFile(path, static_cast<const char*>(pickle.data()), 241 if (!file_util::WriteFile(path, static_cast<const char*>(pickle.data()),
243 pickle.size())) { 242 pickle.size())) {
244 SetError("Could not write message catalogs to disk."); 243 SetError("Could not write message catalogs to disk.");
245 return false; 244 return false;
246 } 245 }
247 246
248 return true; 247 return true;
249 } 248 }
250 249
251 // static 250 // static
252 bool ExtensionUnpacker::ReadImagesFromFile(const FilePath& extension_path, 251 bool Unpacker::ReadImagesFromFile(const FilePath& extension_path,
253 DecodedImages* images) { 252 DecodedImages* images) {
254 FilePath path = extension_path.AppendASCII(filenames::kDecodedImagesFilename); 253 FilePath path = extension_path.AppendASCII(filenames::kDecodedImagesFilename);
255 std::string file_str; 254 std::string file_str;
256 if (!file_util::ReadFileToString(path, &file_str)) 255 if (!file_util::ReadFileToString(path, &file_str))
257 return false; 256 return false;
258 257
259 IPC::Message pickle(file_str.data(), file_str.size()); 258 IPC::Message pickle(file_str.data(), file_str.size());
260 PickleIterator iter(pickle); 259 PickleIterator iter(pickle);
261 return IPC::ReadParam(&pickle, &iter, images); 260 return IPC::ReadParam(&pickle, &iter, images);
262 } 261 }
263 262
264 // static 263 // static
265 bool ExtensionUnpacker::ReadMessageCatalogsFromFile( 264 bool Unpacker::ReadMessageCatalogsFromFile(const FilePath& extension_path,
266 const FilePath& extension_path, DictionaryValue* catalogs) { 265 DictionaryValue* catalogs) {
267 FilePath path = extension_path.AppendASCII( 266 FilePath path = extension_path.AppendASCII(
268 filenames::kDecodedMessageCatalogsFilename); 267 filenames::kDecodedMessageCatalogsFilename);
269 std::string file_str; 268 std::string file_str;
270 if (!file_util::ReadFileToString(path, &file_str)) 269 if (!file_util::ReadFileToString(path, &file_str))
271 return false; 270 return false;
272 271
273 IPC::Message pickle(file_str.data(), file_str.size()); 272 IPC::Message pickle(file_str.data(), file_str.size());
274 PickleIterator iter(pickle); 273 PickleIterator iter(pickle);
275 return IPC::ReadParam(&pickle, &iter, catalogs); 274 return IPC::ReadParam(&pickle, &iter, catalogs);
276 } 275 }
277 276
278 bool ExtensionUnpacker::AddDecodedImage(const FilePath& path) { 277 bool Unpacker::AddDecodedImage(const FilePath& path) {
279 // Make sure it's not referencing a file outside the extension's subdir. 278 // Make sure it's not referencing a file outside the extension's subdir.
280 if (path.IsAbsolute() || PathContainsParentDirectory(path)) { 279 if (path.IsAbsolute() || PathContainsParentDirectory(path)) {
281 SetError(kPathNamesMustBeAbsoluteOrLocalError); 280 SetError(kPathNamesMustBeAbsoluteOrLocalError);
282 return false; 281 return false;
283 } 282 }
284 283
285 SkBitmap image_bitmap = DecodeImage(temp_install_dir_.Append(path)); 284 SkBitmap image_bitmap = DecodeImage(temp_install_dir_.Append(path));
286 if (image_bitmap.isNull()) { 285 if (image_bitmap.isNull()) {
287 SetError(kCouldNotDecodeImageError); 286 SetError(kCouldNotDecodeImageError);
288 return false; 287 return false;
289 } 288 }
290 289
291 decoded_images_.push_back(MakeTuple(image_bitmap, path)); 290 decoded_images_.push_back(MakeTuple(image_bitmap, path));
292 return true; 291 return true;
293 } 292 }
294 293
295 bool ExtensionUnpacker::ReadMessageCatalog(const FilePath& message_path) { 294 bool Unpacker::ReadMessageCatalog(const FilePath& message_path) {
296 std::string error; 295 std::string error;
297 JSONFileValueSerializer serializer(message_path); 296 JSONFileValueSerializer serializer(message_path);
298 scoped_ptr<DictionaryValue> root( 297 scoped_ptr<DictionaryValue> root(
299 static_cast<DictionaryValue*>(serializer.Deserialize(NULL, &error))); 298 static_cast<DictionaryValue*>(serializer.Deserialize(NULL, &error)));
300 if (!root.get()) { 299 if (!root.get()) {
301 string16 messages_file = message_path.LossyDisplayName(); 300 string16 messages_file = message_path.LossyDisplayName();
302 if (error.empty()) { 301 if (error.empty()) {
303 // If file is missing, Deserialize will fail with empty error. 302 // If file is missing, Deserialize will fail with empty error.
304 SetError(base::StringPrintf("%s %s", errors::kLocalesMessagesFileMissing, 303 SetError(base::StringPrintf("%s %s", errors::kLocalesMessagesFileMissing,
305 UTF16ToUTF8(messages_file).c_str())); 304 UTF16ToUTF8(messages_file).c_str()));
(...skipping 15 matching lines...) Expand all
321 std::string dir_name = relative_path.DirName().MaybeAsASCII(); 320 std::string dir_name = relative_path.DirName().MaybeAsASCII();
322 if (dir_name.empty()) { 321 if (dir_name.empty()) {
323 NOTREACHED(); 322 NOTREACHED();
324 return false; 323 return false;
325 } 324 }
326 parsed_catalogs_->Set(dir_name, root.release()); 325 parsed_catalogs_->Set(dir_name, root.release());
327 326
328 return true; 327 return true;
329 } 328 }
330 329
331 void ExtensionUnpacker::SetError(const std::string &error) { 330 void Unpacker::SetError(const std::string &error) {
332 error_message_ = UTF8ToUTF16(error); 331 error_message_ = UTF8ToUTF16(error);
333 } 332 }
333
334 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/unpacker.h ('k') | chrome/common/extensions/unpacker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698