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