Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/browser/media_galleries/fileapi/supported_image_type_validator. h" | 5 #include "chrome/browser/media_galleries/fileapi/scanning_file_validator.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/files/scoped_platform_file_closer.h" | 9 #include "base/files/scoped_platform_file_closer.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
| 14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 15 #include "base/threading/thread_restrictions.h" | 15 #include "base/threading/thread_restrictions.h" |
| 16 #include "chrome/browser/image_decoder.h" | |
| 17 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
| 18 | 17 |
| 18 #if defined(OS_WIN) | |
| 19 #include "base/file_util.h" | |
| 20 #endif | |
| 21 | |
| 19 using content::BrowserThread; | 22 using content::BrowserThread; |
| 20 | 23 |
| 21 namespace chrome { | 24 namespace chrome { |
| 22 | 25 |
| 23 namespace { | 26 namespace { |
| 24 | 27 |
| 25 // Arbitrary limit to sanity check the file size. | 28 // Arbitrary limit to sanity check the file size. |
| 26 const int kMaxImageFileSize = 50*1014*1024; | 29 const int kMaxImageFileSize = 50*1014*1024; |
| 27 | 30 |
| 28 scoped_ptr<std::string> ReadOnFileThread(const base::FilePath& path) { | 31 scoped_ptr<std::string> ReadOnFileThread(const base::FilePath& path) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 44 result.reset(new std::string); | 47 result.reset(new std::string); |
| 45 result->resize(file_info.size); | 48 result->resize(file_info.size); |
| 46 if (base::ReadPlatformFile(file, 0, string_as_array(result.get()), | 49 if (base::ReadPlatformFile(file, 0, string_as_array(result.get()), |
| 47 file_info.size) != file_info.size) { | 50 file_info.size) != file_info.size) { |
| 48 result.reset(); | 51 result.reset(); |
| 49 } | 52 } |
| 50 | 53 |
| 51 return result.Pass(); | 54 return result.Pass(); |
| 52 } | 55 } |
| 53 | 56 |
| 54 class ImageDecoderDelegateAdapter : public ImageDecoder::Delegate { | 57 #if defined(OS_WIN) |
| 55 public: | 58 base::PlatformFileError ScanFile( |
| 56 ImageDecoderDelegateAdapter( | 59 const base::FilePath& dest_platform_path) { |
| 57 scoped_ptr<std::string> data, | 60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 58 const fileapi::CopyOrMoveFileValidator::ResultCallback& callback) | 61 base::PlatformFileError result = base::PLATFORM_FILE_OK; |
| 59 : data_(data.Pass()), | |
| 60 callback_(callback) { | |
| 61 DCHECK(data_); | |
| 62 } | |
| 63 | 62 |
| 64 const std::string& data() { | 63 // Execute an AV check of the transferred file. S_OK means |
| 65 return *data_; | 64 // the file was OK. Other results may indicate the file was |
| 66 } | 65 // deleted. Any other results, including E_FAIL and |
| 66 // INET_E_SECURITY_PROBLEM, are notified as security errors. | |
| 67 HRESULT scan_result = | |
| 68 base::ScanAndSaveDownloadedFile(dest_platform_path, std::string()); | |
| 69 if (scan_result != S_OK) | |
| 70 result = base::PLATFORM_FILE_ERROR_SECURITY; | |
| 67 | 71 |
| 68 // ImageDecoder::Delegate methods. | 72 return result; |
| 69 virtual void OnImageDecoded(const ImageDecoder* /*decoder*/, | 73 } |
| 70 const SkBitmap& /*decoded_image*/) OVERRIDE { | 74 #endif |
| 71 callback_.Run(base::PLATFORM_FILE_OK); | |
| 72 delete this; | |
| 73 } | |
| 74 | 75 |
| 75 virtual void OnDecodeImageFailed(const ImageDecoder* /*decoder*/) OVERRIDE { | |
| 76 callback_.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
| 77 delete this; | |
| 78 } | |
| 79 | |
| 80 private: | |
| 81 scoped_ptr<std::string> data_; | |
| 82 fileapi::CopyOrMoveFileValidator::ResultCallback callback_; | |
| 83 | |
| 84 DISALLOW_COPY_AND_ASSIGN(ImageDecoderDelegateAdapter); | |
| 85 }; | |
| 86 | 76 |
| 87 } // namespace | 77 } // namespace |
| 88 | 78 |
| 89 SupportedImageTypeValidator::~SupportedImageTypeValidator() {} | 79 SupportedImageTypeValidator::~SupportedImageTypeValidator() {} |
|
Lei Zhang
2013/08/05 22:42:40
This isn't right. Shouldn't it be ScanningFileVali
Greg Billock
2013/08/05 23:06:12
Yes. I'm updating it in the next patchset. This wa
| |
| 90 | 80 |
| 91 // static | |
| 92 bool SupportedImageTypeValidator::SupportsFileType(const base::FilePath& path) { | |
| 93 base::FilePath::StringType extension = path.Extension(); | |
| 94 return extension == FILE_PATH_LITERAL(".bmp") || | |
| 95 extension == FILE_PATH_LITERAL(".gif") || | |
| 96 extension == FILE_PATH_LITERAL(".jfif") || | |
| 97 extension == FILE_PATH_LITERAL(".jpeg") || | |
| 98 extension == FILE_PATH_LITERAL(".jpg") || | |
| 99 extension == FILE_PATH_LITERAL(".pjp") || | |
| 100 extension == FILE_PATH_LITERAL(".pjpeg") || | |
| 101 extension == FILE_PATH_LITERAL(".png") || | |
| 102 extension == FILE_PATH_LITERAL(".webp"); | |
| 103 } | |
| 104 | |
| 105 void SupportedImageTypeValidator::StartPreWriteValidation( | 81 void SupportedImageTypeValidator::StartPreWriteValidation( |
| 106 const ResultCallback& result_callback) { | 82 const ResultCallback& result_callback) { |
| 107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 108 DCHECK(callback_.is_null()); | 84 DCHECK(callback_.is_null()); |
| 109 callback_ = result_callback; | 85 callback_ = result_callback; |
| 110 | 86 |
| 111 BrowserThread::PostTaskAndReplyWithResult( | 87 BrowserThread::PostTaskAndReplyWithResult( |
| 112 BrowserThread::FILE, | 88 BrowserThread::FILE, |
| 113 FROM_HERE, | 89 FROM_HERE, |
| 114 base::Bind(&ReadOnFileThread, path_), | 90 base::Bind(&ReadOnFileThread, path_), |
| 115 base::Bind(&SupportedImageTypeValidator::OnFileOpen, | 91 base::Bind(&SupportedImageTypeValidator::OnFileOpen, |
| 116 weak_factory_.GetWeakPtr())); | 92 weak_factory_.GetWeakPtr())); |
| 117 } | 93 } |
| 118 | 94 |
| 119 void SupportedImageTypeValidator::StartPostWriteValidation( | 95 void SupportedImageTypeValidator::StartPostWriteValidation( |
| 120 const base::FilePath& dest_platform_path, | 96 const base::FilePath& dest_platform_path, |
| 121 const ResultCallback& result_callback) { | 97 const ResultCallback& result_callback) { |
| 122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 123 post_write_callback_ = result_callback; | |
| 124 | 99 |
| 125 // TODO(gbillock): Insert AV call here in the right validator. | 100 #if defined(OS_WIN) |
| 101 BrowserThread::PostTaskAndReplyWithResult( | |
| 102 BrowserThread::FILE, | |
| 103 FROM_HERE, | |
| 104 base::Bind(&ScanFile, dest_platform_path), | |
| 105 result_callback); | |
| 106 #else | |
| 126 BrowserThread::PostTask( | 107 BrowserThread::PostTask( |
| 127 BrowserThread::IO, | 108 BrowserThread::IO, |
| 128 FROM_HERE, | 109 FROM_HERE, |
| 129 base::Bind(post_write_callback_, base::PLATFORM_FILE_OK)); | 110 base::Bind(result_callback, base::PLATFORM_FILE_OK)); |
| 111 #endif | |
| 130 } | 112 } |
| 131 | 113 |
| 132 SupportedImageTypeValidator::SupportedImageTypeValidator( | 114 SupportedImageTypeValidator::SupportedImageTypeValidator( |
| 133 const base::FilePath& path) | 115 const base::FilePath& path) |
| 134 : path_(path), | 116 : path_(path), |
| 135 weak_factory_(this) { | 117 weak_factory_(this) { |
| 136 } | 118 } |
| 137 | 119 |
| 138 void SupportedImageTypeValidator::OnFileOpen(scoped_ptr<std::string> data) { | 120 void SupportedImageTypeValidator::OnFileOpen(scoped_ptr<std::string> data) { |
| 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 140 if (!data.get()) { | 122 if (!data.get()) { |
| 141 callback_.Run(base::PLATFORM_FILE_ERROR_SECURITY); | 123 callback_.Run(base::PLATFORM_FILE_ERROR_SECURITY); |
| 142 return; | 124 return; |
| 143 } | 125 } |
| 144 | 126 |
| 145 // |adapter| will delete itself after a completion message is received. | 127 BrowserThread::PostTask( |
| 146 ImageDecoderDelegateAdapter* adapter = | 128 BrowserThread::IO, |
| 147 new ImageDecoderDelegateAdapter(data.Pass(), callback_); | 129 FROM_HERE, |
| 148 decoder_ = new ImageDecoder(adapter, adapter->data(), | 130 base::Bind(callback_, base::PLATFORM_FILE_OK)); |
| 149 ImageDecoder::DEFAULT_CODEC); | |
| 150 decoder_->Start(content::BrowserThread::GetMessageLoopProxyForThread( | |
| 151 BrowserThread::IO)); | |
| 152 } | 131 } |
| 153 | 132 |
| 154 } // namespace chrome | 133 } // namespace chrome |
| OLD | NEW |