blob: 0b7a54c51f7224df91f508ce945c78f5af1df6b3 [file]
// Copyright 2006 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SESSIONS_CORE_SESSION_COMMAND_H_
#define COMPONENTS_SESSIONS_CORE_SESSION_COMMAND_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>
#include "base/containers/span.h"
#include "components/os_crypt/async/common/encryptor.h"
#include "components/sessions/core/sessions_export.h"
namespace base {
class Pickle;
class PickleIterator;
} // namespace base
namespace sessions {
// SessionCommand stores information used for restoring a session.
// It contains an identifier ("id") and arbitrary chunk of data ("contents").
//
// The meaning of the identifier and the contents are specific to the service
// creating them.
//
// Both TabRestoreService and SessionService use SessionCommands to store data
// on disk using the CommandStorageManager.
//
// There are two ways to create a SessionCommand:
// . Specify the size of the data block to create. This is useful for
// commands that have a fixed size.
// . From a pickle, this is useful for commands whose length varies.
class SESSIONS_EXPORT SessionCommand {
public:
// The type of the identifier.
using id_type = uint8_t;
// The type of the size of the contents.
using size_type = uint16_t;
// Creates a session command with the specified id. This allocates a buffer
// of size |size| that must be filled via contents().
SessionCommand(id_type id, size_type size);
// Convenience constructor that creates a session command with the specified
// id whose contents is populated from the contents of pickle.
SessionCommand(id_type id, const base::Pickle& pickle);
SessionCommand(const SessionCommand&) = delete;
SessionCommand& operator=(const SessionCommand&) = delete;
bool operator==(const SessionCommand& command) const;
std::unique_ptr<SessionCommand> Clone() const;
// An identifier for the command. The meaning of the identifier is specific
// to the service that creates the command.
id_type id() const { return id_; }
// The maximum size of the |contents|.
// Note that this is less than UINT16_MAX.
// If this size is exceeded, the contents will be truncated in Serialize().
static constexpr size_t kMaxContentSize =
std::numeric_limits<size_type>::max() - sizeof(id_type);
// The contents of the command. This is an arbitrary chunk of data whose
// meaning is specific to the service that creates the command.
base::span<const uint8_t> contents() const {
return base::as_byte_span(contents_);
}
base::span<uint8_t> contents() {
return base::as_writable_byte_span(contents_);
}
// Convenience for extracting the data to a target. Returns false if
// the destination span's size is not equal to the size of data this
// command contains.
bool GetContents(base::span<uint8_t> dest) const;
// Convenience for extracting the data to a target struct. Returns false if
// the destination's size is not equal to the size of data this command
// contains.
template <typename T>
bool GetContents(T& dest) const {
if constexpr (std::has_unique_object_representations_v<T>) {
return GetContents(base::byte_span_from_ref(dest));
} else {
return GetContents(
base::byte_span_from_ref(base::allow_nonunique_obj, dest));
}
}
// Returns an iterator for reading the contents.
base::PickleIterator ContentsAsPickle() const;
// Serializes the SessionCommand (e.g., so that it can be written to a file).
// The serialized form includes the size of the command, the id, and the
// contents.
// If the size of the contents is greater than kMaxContentSize, the contents
// will be truncated.
// If encryptor is nullptr, the contents will be cleartext.
// If an encryptor is provided, the contents will be encrypted.
// If an error occurs, an empty vector will be returned.
std::vector<uint8_t> Serialize(os_crypt_async::Encryptor* encryptor) const;
// Deserializes the data into a SessionCommand (e.g., for reading from a
// file). It is expected that the data was serialized using Serialize().
// Returns the total serialized size of the command if there is enough data
// to determine it, or std::nullopt otherwise.
// encrypted: whether the data was encrypted during serialization.
static std::optional<size_t> GetSerializedSize(base::span<const uint8_t> data,
bool encrypted);
// Deserializes a SessionCommand that was serialized using Serialize()
// E.g., for reading from a file.
// If encryptor is nullptr, the data is assumed to be cleartext.
// If an encryptor is provided, the contents will be decrypted.
// If an error occurs, nullptr will be returned.
static std::unique_ptr<SessionCommand> Deserialize(
base::span<const uint8_t> data,
os_crypt_async::Encryptor* encryptor);
private:
std::vector<uint8_t> SerializeAsCleartext() const;
std::vector<uint8_t> SerializeWithEncryption(
const os_crypt_async::Encryptor& encryptor) const;
static std::unique_ptr<SessionCommand> DeserializeCleartext(
base::span<const uint8_t> data);
static std::unique_ptr<SessionCommand> DeserializeEncrypted(
base::span<const uint8_t> data,
const os_crypt_async::Encryptor& encryptor);
const id_type id_;
std::string contents_;
};
} // namespace sessions
#endif // COMPONENTS_SESSIONS_CORE_SESSION_COMMAND_H_