1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/supported_image_type_validator.h" 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/bind.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/callback.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/files/file.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/location.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/weak_ptr.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/stl_util.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/image_decoder.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using content::BrowserThread; 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Arbitrary limit to sanity check the file size. 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kMaxImageFileSize = 50*1014*1024; 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<std::string> ReadOnFileThread(const base::FilePath& path) { 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::ThreadRestrictions::AssertIOAllowed(); 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<std::string> result; 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!file.IsValid()) 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result.Pass(); 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Info file_info; 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!file.GetInfo(&file_info) || 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_info.size > kMaxImageFileSize) { 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result.Pass(); 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result.reset(new std::string); 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result->resize(file_info.size); 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (file.Read(0, string_as_array(result.get()), file_info.size) != 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_info.size) { 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result.reset(); 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result.Pass(); 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ImageDecoderDelegateAdapter : public ImageDecoder::Delegate { 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ImageDecoderDelegateAdapter( 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<std::string> data, 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const storage::CopyOrMoveFileValidator::ResultCallback& callback) 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : data_(data.Pass()), callback_(callback) { 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(data_); 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& data() { 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return *data_; 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // ImageDecoder::Delegate methods. 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void OnImageDecoded(const ImageDecoder* /*decoder*/, 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkBitmap& /*decoded_image*/) OVERRIDE { 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_OK); 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delete this; 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void OnDecodeImageFailed(const ImageDecoder* /*decoder*/) OVERRIDE { 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_ERROR_SECURITY); 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delete this; 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<std::string> data_; 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::CopyOrMoveFileValidator::ResultCallback callback_; 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImageDecoderDelegateAdapter); 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SupportedImageTypeValidator::~SupportedImageTypeValidator() {} 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool SupportedImageTypeValidator::SupportsFileType(const base::FilePath& path) { 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FilePath::StringType extension = path.Extension(); 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return extension == FILE_PATH_LITERAL(".bmp") || 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".gif") || 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".jfif") || 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".jpeg") || 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".jpg") || 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".pjp") || 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".pjpeg") || 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".png") || 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".webp"); 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 100a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid SupportedImageTypeValidator::StartPreWriteValidation( 101a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const ResultCallback& result_callback) { 102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(callback_.is_null()); 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_ = result_callback; 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BrowserThread::PostTaskAndReplyWithResult( 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BrowserThread::FILE, 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FROM_HERE, 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&ReadOnFileThread, path_), 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&SupportedImageTypeValidator::OnFileOpen, 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_factory_.GetWeakPtr())); 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SupportedImageTypeValidator::SupportedImageTypeValidator( 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::FilePath& path) 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : path_(path), 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_factory_(this) { 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SupportedImageTypeValidator::OnFileOpen(scoped_ptr<std::string> data) { 121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!data.get()) { 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_ERROR_SECURITY); 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // |adapter| will delete itself after a completion message is received. 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ImageDecoderDelegateAdapter* adapter = 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new ImageDecoderDelegateAdapter(data.Pass(), callback_); 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) decoder_ = new ImageDecoder(adapter, adapter->data(), 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ImageDecoder::DEFAULT_CODEC); 1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) decoder_->Start(content::BrowserThread::GetMessageLoopProxyForThread( 1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserThread::IO)); 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 135