// Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef EXTENSIONS_BROWSER_IMAGE_SANITIZER_H_ #define EXTENSIONS_BROWSER_IMAGE_SANITIZER_H_ #include #include #include #include #include #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/data_decoder/public/mojom/image_decoder.mojom.h" class SkBitmap; namespace data_decoder { class DataDecoder; } namespace extensions { // This class takes potentially unsafe images and decodes them in a sandboxed // process, then reencodes them so that they can later be safely used in the // browser process. class ImageSanitizer { public: enum class Status { kSuccess = 0, kImagePathError, kFileReadError, kFileDeleteError, kDecodingError, kEncodingError, kFileWriteError, kServiceError, // The data-decoder service crashed. }; // Callback invoked when the image sanitization is is done. If status is an // error, |path| points to the file that caused the error. using SanitizationDoneCallback = base::OnceCallback; // Called on a background thread when an image has been decoded. using ImageDecodedCallback = base::RepeatingCallback; // Creates an ImageSanitizer and starts the sanitization of the images in // |image_relative_paths|. These paths should be relative and not reference // their parent dir or an kImagePathError will be reported to |done_callback|. // These relative paths are resolved against |image_dir|. // |decoder| should be a DataDecoder instance to use for image decoding. // |done_callback| is invoked asynchronously when all images have been // sanitized or if an error occurred. // If the returned ImageSanitizer instance is deleted, |done_callback| and // |image_decoded_callback| are not called and the sanitization stops promptly // (some background tasks may still run). static std::unique_ptr CreateAndStart( data_decoder::DataDecoder* decoder, const base::FilePath& image_dir, const std::set& image_relative_paths, ImageDecodedCallback image_decoded_callback, SanitizationDoneCallback done_callback, const scoped_refptr& task_runner); ~ImageSanitizer(); private: ImageSanitizer( const base::FilePath& image_dir, const std::set& image_relative_paths, ImageDecodedCallback image_decoded_callback, SanitizationDoneCallback done_callback, const scoped_refptr& io_task_runner); void Start(data_decoder::DataDecoder* decoder); void ImageFileRead( const base::FilePath& image_path, std::tuple, bool, bool> read_and_delete_result); void ImageDecoded(const base::FilePath& image_path, const SkBitmap& decoded_image); void ImageReencoded(const base::FilePath& image_path, std::pair> result); void ImageWritten(const base::FilePath& image_path, int expected_size, int actual_size); void ReportSuccess(); void ReportError(Status status, const base::FilePath& path); void CleanUp(); base::FilePath image_dir_; std::set image_paths_; ImageDecodedCallback image_decoded_callback_; SanitizationDoneCallback done_callback_; scoped_refptr io_task_runner_; mojo::Remote image_decoder_; base::WeakPtrFactory weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(ImageSanitizer); }; } // namespace extensions #endif // EXTENSIONS_BROWSER_IMAGE_SANITIZER_H_