blob: f592d496fd1dceb0c06ccaeb044ecc55dea96693 [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_BROWSER_JSON_FILE_SANITIZER_H_
#define EXTENSIONS_BROWSER_JSON_FILE_SANITIZER_H_
#include <memory>
#include <optional>
#include <set>
#include <string>
#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/types/expected.h"
#include "base/values.h"
#include "mojo/public/cpp/bindings/remote.h"
namespace extensions {
// This class takes potentially unsafe JSON files, decodes them in a sandboxed
// process, then reencodes them so that they can later be parsed safely from the
// browser process.
// Note that at this time it this is limited to JSON files that contain a
// unique dictionary as their root and will fail with a kDecodingError if that
// is not the case.
class JsonFileSanitizer {
public:
enum class Error {
kFileReadError,
kFileDeleteError,
kDecodingError,
kSerializingError,
kFileWriteError,
};
// Callback invoked when the JSON sanitization is is done.
using Callback = base::OnceCallback<void(base::expected<void, Error>)>;
// Creates a JsonFileSanitizer and starts the sanitization of the JSON files
// in `file_paths`.
// `callback` is invoked asynchronously when all JSON files have been
// sanitized or if an error occurred.
// If the returned JsonFileSanitizer instance is deleted before `callback` was
// invoked, then `callback` is never invoked and the sanitization stops
// promptly (some background tasks may still run).
static std::unique_ptr<JsonFileSanitizer> CreateAndStart(
const std::set<base::FilePath>& file_paths,
Callback callback,
const scoped_refptr<base::SequencedTaskRunner>& io_task_runner);
JsonFileSanitizer(const JsonFileSanitizer&) = delete;
JsonFileSanitizer& operator=(const JsonFileSanitizer&) = delete;
~JsonFileSanitizer();
private:
JsonFileSanitizer(
Callback callback,
const scoped_refptr<base::SequencedTaskRunner>& io_task_runner);
void Start(const std::set<base::FilePath>& file_paths);
// Note: unlike all other methods, this executes on `io_task_runner_`.
static base::expected<void, Error> ProcessFile(const base::FilePath& path);
void OnProcessedFile(base::expected<void, Error> result);
void ReportSuccess();
void ReportError(Error error);
size_t remaining_callbacks_ = 0;
Callback callback_;
scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
base::WeakPtrFactory<JsonFileSanitizer> weak_factory_{this};
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_JSON_FILE_SANITIZER_H_