supported_image_type_validator.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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, 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const fileapi::CopyOrMoveFileValidator::ResultCallback& callback) 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : data_(data.Pass()), 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_(callback) { 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(data_); 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& data() { 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return *data_; 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // ImageDecoder::Delegate methods. 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void OnImageDecoded(const ImageDecoder* /*decoder*/, 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkBitmap& /*decoded_image*/) OVERRIDE { 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_OK); 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delete this; 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void OnDecodeImageFailed(const ImageDecoder* /*decoder*/) OVERRIDE { 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_ERROR_SECURITY); 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delete this; 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<std::string> data_; 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fileapi::CopyOrMoveFileValidator::ResultCallback callback_; 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImageDecoderDelegateAdapter); 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SupportedImageTypeValidator::~SupportedImageTypeValidator() {} 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool SupportedImageTypeValidator::SupportsFileType(const base::FilePath& path) { 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FilePath::StringType extension = path.Extension(); 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return extension == FILE_PATH_LITERAL(".bmp") || 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".gif") || 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".jfif") || 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".jpeg") || 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".jpg") || 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".pjp") || 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".pjpeg") || 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".png") || 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".webp"); 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 101a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid SupportedImageTypeValidator::StartPreWriteValidation( 102a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const ResultCallback& result_callback) { 103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(callback_.is_null()); 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_ = result_callback; 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BrowserThread::PostTaskAndReplyWithResult( 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BrowserThread::FILE, 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FROM_HERE, 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&ReadOnFileThread, path_), 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&SupportedImageTypeValidator::OnFileOpen, 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_factory_.GetWeakPtr())); 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SupportedImageTypeValidator::SupportedImageTypeValidator( 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::FilePath& path) 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : path_(path), 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_factory_(this) { 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SupportedImageTypeValidator::OnFileOpen(scoped_ptr<std::string> data) { 122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!data.get()) { 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_ERROR_SECURITY); 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // |adapter| will delete itself after a completion message is received. 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ImageDecoderDelegateAdapter* adapter = 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new ImageDecoderDelegateAdapter(data.Pass(), callback_); 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) decoder_ = new ImageDecoder(adapter, adapter->data(), 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ImageDecoder::DEFAULT_CODEC); 1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) decoder_->Start(content::BrowserThread::GetMessageLoopProxyForThread( 1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserThread::IO)); 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 136