chromium/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.h"

#include <cstdint>
#include <memory>
#include <utility>

#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/numerics/safe_conversions.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_request.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_value.h"
#include "third_party/blink/renderer/platform/blob/blob_data.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/snappy/src/snappy.h"

namespace blink {

namespace {

// V8 values are stored on disk by IndexedDB using the format implemented in
// SerializedScriptValue (SSV). The wrapping detection logic in
// IDBValueUnwrapper::IsWrapped() must be able to distinguish between SSV byte
// sequences produced and byte sequences expressing the fact that an IDBValue
// has been wrapped and requires post-processing.
//
// The detection logic takes advantage of the highly regular structure around
// SerializedScriptValue. A version 17 byte sequence always starts with the
// following four bytes:
//
// 1) 0xFF - kVersionTag
// 2) 0x11 - Blink wrapper version, 17
// 3) 0xFF - kVersionTag
// 4) 0x0D - V8 serialization version, currently 13, doesn't matter
//
// It follows that SSV will never produce byte sequences starting with 0xFF,
// 0x11, and any value except for 0xFF. If the SSV format changes, the version
// will have to be bumped.

// The SSV format version whose encoding hole is (ab)used for wrapping.
static const uint8_t kRequiresProcessingSSVPseudoVersion =;

// SSV processing command replacing the SSV data bytes with a Blob's contents.
//
// 1) 0xFF - kVersionTag
// 2) 0x11 - kRequiresProcessingSSVPseudoVersion
// 3) 0x01 - kReplaceWithBlob
// 4) varint - Blob size
// 5) varint - the offset of the SSV-wrapping Blob in the IDBValue list of Blobs
//             (should always be the last Blob)
static const uint8_t kReplaceWithBlob =;

// A similar approach is used to notate compressed data.
// 1) 0xFF - kVersionTag
// 2) 0x11 - kRequiresProcessingSSVPseudoVersion
// 3) 0x02 - kCompressedWithSnappy
// 4) the compressed data

// Data is compressed using Snappy in a single chunk (i.e. without framing).
static const uint8_t kCompressedWithSnappy =;

// The number of header bytes in the above scheme.
static const size_t kHeaderSize =;

// Evaluates whether to transmit and store a payload in its compressed form
// based on the compression achieved. Decompressing has a cost in terms of both
// CPU and memory usage, so we skip it for less compressible or jumbo data.
bool ShouldTransmitCompressed(size_t uncompressed_length,
                              size_t compressed_length) {}

}  // namespace

IDBValueWrapper::IDBValueWrapper(
    v8::Isolate* isolate,
    v8::Local<v8::Value> value,
    SerializedScriptValue::SerializeOptions::WasmSerializationPolicy
        wasm_policy,
    ExceptionState& exception_state) {}

// Explicit destructor in the .cpp file, to move the dependency on the
// BlobDataHandle definition away from the header file.
IDBValueWrapper::~IDBValueWrapper() = default;

void IDBValueWrapper::Clone(ScriptState* script_state, ScriptValue* clone) {}

// static
void IDBValueWrapper::WriteVarInt(unsigned value, Vector<char>& output) {}

void IDBValueWrapper::DoneCloning() {}

bool IDBValueWrapper::ShouldCompress(size_t uncompressed_length) const {}

void IDBValueWrapper::MaybeCompress() {}

void IDBValueWrapper::MaybeStoreInBlob() {}

Vector<char> IDBValueWrapper::TakeWireBytes() {}

IDBValueUnwrapper::IDBValueUnwrapper() {}

// static
bool IDBValueUnwrapper::IsWrapped(IDBValue* value) {}

// static
bool IDBValueUnwrapper::IsWrapped(
    const Vector<std::unique_ptr<IDBValue>>& values) {}

// static
void IDBValueUnwrapper::Unwrap(Vector<char>&& wrapper_blob_content,
                               IDBValue& wrapped_value) {}

// static
bool IDBValueUnwrapper::Decompress(const Vector<char>& buffer,
                                   Vector<char>* out_buffer) {}

bool IDBValueUnwrapper::Parse(IDBValue* value) {}

scoped_refptr<BlobDataHandle> IDBValueUnwrapper::WrapperBlobHandle() {}

bool IDBValueUnwrapper::ReadVarInt(unsigned& value) {}

bool IDBValueUnwrapper::ReadBytes(Vector<uint8_t>& value) {}

bool IDBValueUnwrapper::Reset() {}

}  // namespace blink