supported_image_type_validator.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/location.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/weak_ptr.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/stl_util.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.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 chrome { 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Arbitrary limit to sanity check the file size. 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kMaxImageFileSize = 50*1014*1024; 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct PlatformFileCloser { 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void operator()(base::PlatformFile* file) const { 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (file && *file != base::kInvalidPlatformFileValue) 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::ClosePlatformFile(*file); 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)typedef scoped_ptr<base::PlatformFile, PlatformFileCloser> 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ScopedPlatformFile; 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_ptr<std::string> ReadOnFileThread(const base::FilePath& path) { 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::ThreadRestrictions::AssertIOAllowed(); 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<std::string> result; 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::PlatformFile file = base::CreatePlatformFile( 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL, NULL); 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ScopedPlatformFile file_closer(&file); 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (file == base::kInvalidPlatformFileValue) 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result.Pass(); 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::PlatformFileInfo file_info; 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!base::GetPlatformFileInfo(file, &file_info) || 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_info.size > kMaxImageFileSize) { 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result.Pass(); 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result.reset(new std::string); 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result->resize(file_info.size); 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (base::ReadPlatformFile(file, 0, string_as_array(result.get()), 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_info.size) != file_info.size) { 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) result.reset(); 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return result.Pass(); 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ImageDecoderDelegateAdapter : public ImageDecoder::Delegate { 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ImageDecoderDelegateAdapter( 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<std::string> data, 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const fileapi::CopyOrMoveFileValidator::ResultCallback& callback) 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : data_(data.Pass()), 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_(callback) { 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(data_); 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& data() { 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return *data_; 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // ImageDecoder::Delegate methods. 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void OnImageDecoded(const ImageDecoder* /*decoder*/, 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkBitmap& /*decoded_image*/) OVERRIDE { 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(callback_, base::PLATFORM_FILE_OK)); 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delete this; 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void OnDecodeImageFailed(const ImageDecoder* /*decoder*/) OVERRIDE { 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(callback_, 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::PLATFORM_FILE_ERROR_SECURITY)); 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delete this; 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<std::string> data_; 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fileapi::CopyOrMoveFileValidator::ResultCallback callback_; 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ImageDecoderDelegateAdapter); 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SupportedImageTypeValidator::~SupportedImageTypeValidator() {} 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool SupportedImageTypeValidator::SupportsFileType(const base::FilePath& path) { 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FilePath::StringType extension = path.Extension(); 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return extension == FILE_PATH_LITERAL(".bmp") || 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".gif") || 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".jfif") || 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".jpeg") || 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".jpg") || 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".pjp") || 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".pjpeg") || 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".png") || 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension == FILE_PATH_LITERAL(".webp"); 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SupportedImageTypeValidator::StartValidation( 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const fileapi::CopyOrMoveFileValidator::ResultCallback& result_callback) { 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(callback_.is_null()); 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_ = result_callback; 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BrowserThread::PostTaskAndReplyWithResult( 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BrowserThread::FILE, 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FROM_HERE, 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&ReadOnFileThread, path_), 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&SupportedImageTypeValidator::OnFileOpen, 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_factory_.GetWeakPtr())); 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)SupportedImageTypeValidator::SupportedImageTypeValidator( 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::FilePath& path) 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : path_(path), 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_factory_(this) { 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SupportedImageTypeValidator::OnFileOpen(scoped_ptr<std::string> data) { 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!data.get()) { 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_.Run(base::PLATFORM_FILE_ERROR_SECURITY); 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // |adapter| will delete itself after a completion message is received. 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ImageDecoderDelegateAdapter* adapter = 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new ImageDecoderDelegateAdapter(data.Pass(), callback_); 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) decoder_ = new ImageDecoder(adapter, adapter->data(), 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ImageDecoder::DEFAULT_CODEC); 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::SequencedWorkerPool* workerpool = BrowserThread::GetBlockingPool(); 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) decoder_->Start(workerpool->GetSequencedTaskRunnerWithShutdownBehavior( 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) workerpool->GetSequenceToken(), 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace chrome 157