// Copyright 2016 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.

#include "third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h"

#include <limits>

#include "base/numerics/checked_math.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_point_init.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/fileapi/file.h"
#include "third_party/blink/renderer/core/fileapi/file_list.h"
#include "third_party/blink/renderer/core/geometry/dom_matrix.h"
#include "third_party/blink/renderer/core/geometry/dom_matrix_read_only.h"
#include "third_party/blink/renderer/core/geometry/dom_point.h"
#include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
#include "third_party/blink/renderer/core/geometry/dom_quad.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/geometry/dom_rect_read_only.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
#include "third_party/blink/renderer/core/messaging/message_port.h"
#include "third_party/blink/renderer/core/mojo/mojo_handle.h"
#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
#include "third_party/blink/renderer/core/streams/readable_stream.h"
#include "third_party/blink/renderer/core/streams/readable_stream_transferring_optimizer.h"
#include "third_party/blink/renderer/core/streams/transform_stream.h"
#include "third_party/blink/renderer/core/streams/writable_stream.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_shared_array_buffer.h"
#include "third_party/blink/renderer/platform/file_metadata.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/date_math.h"
#include "third_party/skia/include/core/SkFilterQuality.h"

namespace blink {

namespace {

// The "Blink-side" serialization version, which defines how Blink will behave
// during the serialization process. The serialization format has two
// "envelopes": an outer one controlled by Blink and an inner one by V8.
//
// They are formatted as follows:
// [version tag] [Blink version] [version tag] [v8 version] ...
//
// Before version 16, there was only a single envelope and the version number
// for both parts was always equal.
//
// See also V8ScriptValueDeserializer.cpp.
const uint32_t kMinVersionForSeparateEnvelope = 16;

// Returns the number of bytes consumed reading the Blink version envelope, and
// sets |*version| to the version. If no Blink envelope was detected, zero is
// returned.
size_t ReadVersionEnvelope(SerializedScriptValue* serialized_script_value,
                           uint32_t* out_version) {
  const uint8_t* raw_data = serialized_script_value->Data();
  const size_t length = serialized_script_value->DataLengthInBytes();
  if (!length || raw_data[0] != kVersionTag)
    return 0;

  // Read a 32-bit unsigned integer from varint encoding.
  uint32_t version = 0;
  size_t i = 1;
  unsigned shift = 0;
  bool has_another_byte;
  do {
    if (i >= length)
      return 0;
    uint8_t byte = raw_data[i];
    if (LIKELY(shift < 32)) {
      version |= static_cast<uint32_t>(byte & 0x7f) << shift;
      shift += 7;
    }
    has_another_byte = byte & 0x80;
    i++;
  } while (has_another_byte);

  // If the version in the envelope is too low, this was not a Blink version
  // envelope.
  if (version < kMinVersionForSeparateEnvelope)
    return 0;

  // Otherwise, we did read the envelope. Hurray!
  *out_version = version;
  return i;
}

MessagePort* CreateEntangledPort(ScriptState* script_state,
                                 const MessagePortChannel& channel) {
  MessagePort* const port =
      MakeGarbageCollected<MessagePort>(*ExecutionContext::From(script_state));
  port->Entangle(channel);
  return port;
}

}  // namespace

V8ScriptValueDeserializer::V8ScriptValueDeserializer(
    ScriptState* script_state,
    UnpackedSerializedScriptValue* unpacked_value,
    const Options& options)
    : V8ScriptValueDeserializer(script_state,
                                unpacked_value,
                                unpacked_value->Value(),
                                options) {}

V8ScriptValueDeserializer::V8ScriptValueDeserializer(
    ScriptState* script_state,
    scoped_refptr<SerializedScriptValue> value,
    const Options& options)
    : V8ScriptValueDeserializer(script_state,
                                nullptr,
                                std::move(value),
                                options) {
  DCHECK(!serialized_script_value_->HasPackedContents())
      << "If the provided SerializedScriptValue could contain packed contents "
         "due to transfer, then it must be unpacked before deserialization. "
         "See SerializedScriptValue::Unpack.";
}

V8ScriptValueDeserializer::V8ScriptValueDeserializer(
    ScriptState* script_state,
    UnpackedSerializedScriptValue* unpacked_value,
    scoped_refptr<SerializedScriptValue> value,
    const Options& options)
    : script_state_(script_state),
      unpacked_value_(unpacked_value),
      serialized_script_value_(value),
      deserializer_(script_state_->GetIsolate(),
                    serialized_script_value_->Data(),
                    serialized_script_value_->DataLengthInBytes(),
                    this),
      transferred_message_ports_(options.message_ports),
      blob_info_array_(options.blob_info) {
  deserializer_.SetSupportsLegacyWireFormat(true);
}

v8::Local<v8::Value> V8ScriptValueDeserializer::Deserialize() {
#if DCHECK_IS_ON()
  DCHECK(!deserialize_invoked_);
  deserialize_invoked_ = true;
#endif

  v8::Isolate* isolate = script_state_->GetIsolate();
  v8::EscapableHandleScope scope(isolate);
  v8::TryCatch try_catch(isolate);
  v8::Local<v8::Context> context = script_state_->GetContext();

  size_t version_envelope_size =
      ReadVersionEnvelope(serialized_script_value_.get(), &version_);
  if (version_envelope_size) {
    const void* blink_envelope;
    bool read_envelope = ReadRawBytes(version_envelope_size, &blink_envelope);
    DCHECK(read_envelope);
    DCHECK_GE(version_, kMinVersionForSeparateEnvelope);
  } else {
    DCHECK_EQ(version_, 0u);
  }

  bool read_header;
  if (!deserializer_.ReadHeader(context).To(&read_header))
    return v8::Null(isolate);
  DCHECK(read_header);

  // If there was no Blink envelope earlier, Blink shares the wire format
  // version from the V8 header.
  if (!version_)
    version_ = deserializer_.GetWireFormatVersion();

  // Prepare to transfer the provided transferables.
  Transfer();

  v8::Local<v8::Value> value;
  if (!deserializer_.ReadValue(context).ToLocal(&value))
    return v8::Null(isolate);
  return scope.Escape(value);
}

void V8ScriptValueDeserializer::Transfer() {
  if (TransferableStreamsEnabled()) {
    // TODO(ricea): Make ExtendableMessageEvent store an
    // UnpackedSerializedScriptValue like MessageEvent does, and then this
    // special case won't be necessary.
    streams_ = std::move(serialized_script_value_->GetStreams());
  }

  // There's nothing else to transfer if the deserializer was not given an
  // unpacked value.
  if (!unpacked_value_)
    return;

  v8::Isolate* isolate = script_state_->GetIsolate();
  v8::Local<v8::Context> context = script_state_->GetContext();
  v8::Local<v8::Object> creation_context = context->Global();

  // Transfer array buffers.
  const auto& array_buffers = unpacked_value_->ArrayBuffers();
  for (unsigned i = 0; i < array_buffers.size(); i++) {
    DOMArrayBufferBase* array_buffer = array_buffers.at(i);
    v8::Local<v8::Value> wrapper =
        ToV8(array_buffer, creation_context, isolate);
    if (array_buffer->IsShared()) {
      // Crash if we are receiving a SharedArrayBuffer and this isn't allowed.
      auto* execution_context = ExecutionContext::From(script_state_);
      CHECK(execution_context->SharedArrayBufferTransferAllowed());

      DCHECK(wrapper->IsSharedArrayBuffer());
      deserializer_.TransferSharedArrayBuffer(
          i, v8::Local<v8::SharedArrayBuffer>::Cast(wrapper));
    } else {
      DCHECK(wrapper->IsArrayBuffer());
      deserializer_.TransferArrayBuffer(
          i, v8::Local<v8::ArrayBuffer>::Cast(wrapper));
    }
  }
}

bool V8ScriptValueDeserializer::ReadUTF8String(String* string) {
  uint32_t utf8_length = 0;
  const void* utf8_data = nullptr;
  if (!ReadUint32(&utf8_length) || !ReadRawBytes(utf8_length, &utf8_data))
    return false;
  *string =
      String::FromUTF8(reinterpret_cast<const LChar*>(utf8_data), utf8_length);

  // Decoding must have failed; this encoding does not distinguish between null
  // and empty strings.
  return !string->IsNull();
}

ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject(
    SerializationTag tag,
    ExceptionState& exception_state) {
  switch (tag) {
    case kBlobTag: {
      if (Version() < 3)
        return nullptr;
      String uuid, type;
      uint64_t size;
      if (!ReadUTF8String(&uuid) || !ReadUTF8String(&type) ||
          !ReadUint64(&size))
        return nullptr;
      auto blob_handle = GetOrCreateBlobDataHandle(uuid, type, size);
      if (!blob_handle)
        return nullptr;
      return MakeGarbageCollected<Blob>(std::move(blob_handle));
    }
    case kBlobIndexTag: {
      if (Version() < 6 || !blob_info_array_)
        return nullptr;
      uint32_t index = 0;
      if (!ReadUint32(&index) || index >= blob_info_array_->size())
        return nullptr;
      const WebBlobInfo& info = (*blob_info_array_)[index];
      auto blob_handle = info.GetBlobHandle();
      if (!blob_handle) {
        blob_handle =
            GetOrCreateBlobDataHandle(info.Uuid(), info.GetType(), info.size());
      }
      if (!blob_handle)
        return nullptr;
      return MakeGarbageCollected<Blob>(std::move(blob_handle));
    }
    case kFileTag:
      return ReadFile();
    case kFileIndexTag:
      return ReadFileIndex();
    case kFileListTag: {
      // This does not presently deduplicate a File object and its entry in a
      // FileList, which is non-standard behavior.
      uint32_t length;
      if (!ReadUint32(&length))
        return nullptr;
      auto* file_list = MakeGarbageCollected<FileList>();
      for (uint32_t i = 0; i < length; i++) {
        if (File* file = ReadFile())
          file_list->Append(file);
        else
          return nullptr;
      }
      return file_list;
    }
    case kFileListIndexTag: {
      // This does not presently deduplicate a File object and its entry in a
      // FileList, which is non-standard behavior.
      uint32_t length;
      if (!ReadUint32(&length))
        return nullptr;
      auto* file_list = MakeGarbageCollected<FileList>();
      for (uint32_t i = 0; i < length; i++) {
        if (File* file = ReadFileIndex())
          file_list->Append(file);
        else
          return nullptr;
      }
      return file_list;
    }
    case kImageBitmapTag: {
      SerializedColorSpace canvas_color_space = SerializedColorSpace::kSRGB;
      SerializedPixelFormat canvas_pixel_format =
          SerializedPixelFormat::kNative8_LegacyObsolete;
      SerializedOpacityMode canvas_opacity_mode =
          SerializedOpacityMode::kOpaque;
      uint32_t origin_clean = 0, is_premultiplied = 0, width = 0, height = 0,
               byte_length = 0;
      const void* pixels = nullptr;
      if (Version() >= 18) {
        // read the list of key pair values for color settings, etc.
        bool is_done = false;
        do {
          ImageSerializationTag image_tag;
          if (!ReadUint32Enum<ImageSerializationTag>(&image_tag))
            return nullptr;
          switch (image_tag) {
            case ImageSerializationTag::kEndTag:
              is_done = true;
              break;
            case ImageSerializationTag::kCanvasColorSpaceTag:
              if (!ReadUint32Enum<SerializedColorSpace>(&canvas_color_space))
                return nullptr;
              break;
            case ImageSerializationTag::kCanvasPixelFormatTag:
              if (!ReadUint32Enum<SerializedPixelFormat>(&canvas_pixel_format))
                return nullptr;
              break;
            case ImageSerializationTag::kCanvasOpacityModeTag:
              if (!ReadUint32Enum<SerializedOpacityMode>(&canvas_opacity_mode))
                return nullptr;
              break;
            case ImageSerializationTag::kOriginCleanTag:
              if (!ReadUint32(&origin_clean) || origin_clean > 1)
                return nullptr;
              break;
            case ImageSerializationTag::kIsPremultipliedTag:
              if (!ReadUint32(&is_premultiplied) || is_premultiplied > 1)
                return nullptr;
              break;
            case ImageSerializationTag::kImageDataStorageFormatTag:
              // Does not apply to ImageBitmap.
              return nullptr;
          }
        } while (!is_done);
      } else if (!ReadUint32(&origin_clean) || origin_clean > 1 ||
                 !ReadUint32(&is_premultiplied) || is_premultiplied > 1) {
        return nullptr;
      }
      if (!ReadUint32(&width) || !ReadUint32(&height) ||
          !ReadUint32(&byte_length) || !ReadRawBytes(byte_length, &pixels))
        return nullptr;
      SkImageInfo info =
          SerializedImageBitmapSettings(canvas_color_space, canvas_pixel_format,
                                        canvas_opacity_mode, is_premultiplied)
              .GetSkImageInfo(width, height);
      base::CheckedNumeric<uint32_t> computed_byte_length =
          info.computeMinByteSize();
      if (!computed_byte_length.IsValid() ||
          computed_byte_length.ValueOrDie() != byte_length)
        return nullptr;
      if (!origin_clean) {
        // Non-origin-clean ImageBitmap serialization/deserialization have
        // been deprecated.
        return nullptr;
      }
      SkPixmap pixmap(info, pixels, info.minRowBytes());
      return MakeGarbageCollected<ImageBitmap>(pixmap, origin_clean);
    }
    case kImageBitmapTransferTag: {
      uint32_t index = 0;
      if (!unpacked_value_)
        return nullptr;
      const auto& transferred_image_bitmaps = unpacked_value_->ImageBitmaps();
      if (!ReadUint32(&index) || index >= transferred_image_bitmaps.size())
        return nullptr;
      return transferred_image_bitmaps[index].Get();
    }
    case kImageDataTag: {
      SerializedColorSpace canvas_color_space = SerializedColorSpace::kSRGB;
      SerializedImageDataStorageFormat image_data_storage_format =
          SerializedImageDataStorageFormat::kUint8Clamped;
      uint32_t width = 0, height = 0;
      const void* pixels = nullptr;
      if (Version() >= 18) {
        bool is_done = false;
        do {
          ImageSerializationTag image_tag;
          if (!ReadUint32Enum<ImageSerializationTag>(&image_tag))
            return nullptr;
          switch (image_tag) {
            case ImageSerializationTag::kEndTag:
              is_done = true;
              break;
            case ImageSerializationTag::kCanvasColorSpaceTag:
              if (!ReadUint32Enum<SerializedColorSpace>(&canvas_color_space))
                return nullptr;
              break;
            case ImageSerializationTag::kImageDataStorageFormatTag:
              if (!ReadUint32Enum<SerializedImageDataStorageFormat>(
                      &image_data_storage_format))
                return nullptr;
              break;
            case ImageSerializationTag::kCanvasPixelFormatTag:
            case ImageSerializationTag::kOriginCleanTag:
            case ImageSerializationTag::kIsPremultipliedTag:
            case ImageSerializationTag::kCanvasOpacityModeTag:
              // Does not apply to ImageData.
              return nullptr;
          }
        } while (!is_done);
      }

      uint64_t byte_length_64 = 0;
      size_t byte_length = 0;
      if (!ReadUint32(&width) || !ReadUint32(&height) ||
          !ReadUint64(&byte_length_64) ||
          !base::MakeCheckedNum(byte_length_64).AssignIfValid(&byte_length) ||
          !ReadRawBytes(byte_length, &pixels)) {
        return nullptr;
      }

      SerializedImageDataSettings settings(canvas_color_space,
                                           image_data_storage_format);
      base::CheckedNumeric<size_t> computed_byte_length = width;
      computed_byte_length *= height;
      computed_byte_length *=
          ImageData::StorageFormatBytesPerPixel(settings.GetStorageFormat());
      if (!computed_byte_length.IsValid() ||
          computed_byte_length.ValueOrDie() != byte_length)
        return nullptr;
      ImageData* image_data = ImageData::ValidateAndCreate(
          width, height, base::nullopt, settings.GetImageDataSettings(),
          exception_state);
      if (!image_data)
        return nullptr;
      SkPixmap image_data_pixmap = image_data->GetSkPixmap();
      DCHECK_EQ(image_data_pixmap.computeByteSize(), byte_length);
      memcpy(image_data_pixmap.writable_addr(), pixels, byte_length);
      return image_data;
    }
    case kDOMPointTag: {
      double x = 0, y = 0, z = 0, w = 1;
      if (!ReadDouble(&x) || !ReadDouble(&y) || !ReadDouble(&z) ||
          !ReadDouble(&w))
        return nullptr;
      return DOMPoint::Create(x, y, z, w);
    }
    case kDOMPointReadOnlyTag: {
      double x = 0, y = 0, z = 0, w = 1;
      if (!ReadDouble(&x) || !ReadDouble(&y) || !ReadDouble(&z) ||
          !ReadDouble(&w))
        return nullptr;
      return DOMPointReadOnly::Create(x, y, z, w);
    }
    case kDOMRectTag: {
      double x = 0, y = 0, width = 0, height = 0;
      if (!ReadDouble(&x) || !ReadDouble(&y) || !ReadDouble(&width) ||
          !ReadDouble(&height))
        return nullptr;
      return DOMRect::Create(x, y, width, height);
    }
    case kDOMRectReadOnlyTag: {
      return ReadDOMRectReadOnly();
    }
    case kDOMQuadTag: {
      DOMPointInit* point_inits[4];
      for (int i = 0; i < 4; ++i) {
        auto* init = DOMPointInit::Create();
        double x = 0, y = 0, z = 0, w = 0;
        if (!ReadDouble(&x) || !ReadDouble(&y) || !ReadDouble(&z) ||
            !ReadDouble(&w))
          return nullptr;
        init->setX(x);
        init->setY(y);
        init->setZ(z);
        init->setW(w);
        point_inits[i] = init;
      }
      return DOMQuad::Create(point_inits[0], point_inits[1], point_inits[2],
                             point_inits[3]);
    }
    case kDOMMatrix2DTag: {
      double values[6];
      for (double& d : values) {
        if (!ReadDouble(&d))
          return nullptr;
      }
      return DOMMatrix::CreateForSerialization(values, base::size(values));
    }
    case kDOMMatrix2DReadOnlyTag: {
      double values[6];
      for (double& d : values) {
        if (!ReadDouble(&d))
          return nullptr;
      }
      return DOMMatrixReadOnly::CreateForSerialization(values,
                                                       base::size(values));
    }
    case kDOMMatrixTag: {
      double values[16];
      for (double& d : values) {
        if (!ReadDouble(&d))
          return nullptr;
      }
      return DOMMatrix::CreateForSerialization(values, base::size(values));
    }
    case kDOMMatrixReadOnlyTag: {
      double values[16];
      for (double& d : values) {
        if (!ReadDouble(&d))
          return nullptr;
      }
      return DOMMatrixReadOnly::CreateForSerialization(values,
                                                       base::size(values));
    }
    case kMessagePortTag: {
      uint32_t index = 0;
      if (!ReadUint32(&index) || !transferred_message_ports_ ||
          index >= transferred_message_ports_->size())
        return nullptr;
      return (*transferred_message_ports_)[index].Get();
    }
    case kMojoHandleTag: {
      uint32_t index = 0;
      if (!RuntimeEnabledFeatures::MojoJSEnabled() || !ReadUint32(&index) ||
          index >= serialized_script_value_->MojoHandles().size()) {
        return nullptr;
      }
      return MakeGarbageCollected<MojoHandle>(
          std::move(serialized_script_value_->MojoHandles()[index]));
    }
    case kOffscreenCanvasTransferTag: {
      uint32_t width = 0, height = 0, canvas_id = 0, client_id = 0, sink_id = 0,
               filter_quality = 0;
      if (!ReadUint32(&width) || !ReadUint32(&height) ||
          !ReadUint32(&canvas_id) || !ReadUint32(&client_id) ||
          !ReadUint32(&sink_id) || !ReadUint32(&filter_quality))
        return nullptr;
      OffscreenCanvas* canvas = OffscreenCanvas::Create(
          ExecutionContext::From(GetScriptState()), width, height);
      canvas->SetPlaceholderCanvasId(canvas_id);
      canvas->SetFrameSinkId(client_id, sink_id);
      if (filter_quality == 0)
        canvas->SetFilterQuality(kNone_SkFilterQuality);
      else
        canvas->SetFilterQuality(kLow_SkFilterQuality);
      return canvas;
    }
    case kReadableStreamTransferTag: {
      if (!TransferableStreamsEnabled())
        return nullptr;
      uint32_t index = 0;
      if (!ReadUint32(&index) || index >= streams_.size()) {
        return nullptr;
      }
      return ReadableStream::Deserialize(
          script_state_,
          CreateEntangledPort(GetScriptState(), streams_[index].channel),
          std::move(streams_[index].readable_optimizer), exception_state);
    }
    case kWritableStreamTransferTag: {
      if (!TransferableStreamsEnabled())
        return nullptr;
      uint32_t index = 0;
      if (!ReadUint32(&index) || index >= streams_.size()) {
        return nullptr;
      }
      return WritableStream::Deserialize(
          script_state_,
          CreateEntangledPort(GetScriptState(), streams_[index].channel),
          std::move(streams_[index].writable_optimizer), exception_state);
    }
    case kTransformStreamTransferTag: {
      if (!TransferableStreamsEnabled())
        return nullptr;
      uint32_t index = 0;
      if (!ReadUint32(&index) ||
          index == std::numeric_limits<decltype(index)>::max() ||
          index + 1 >= streams_.size()) {
        return nullptr;
      }
      MessagePort* const port_for_readable =
          CreateEntangledPort(GetScriptState(), streams_[index].channel);
      MessagePort* const port_for_writable =
          CreateEntangledPort(GetScriptState(), streams_[index + 1].channel);

      // https://streams.spec.whatwg.org/#ts-transfer
      // 1. Let readableRecord be !
      //    StructuredDeserializeWithTransfer(dataHolder.[[readable]], the
      //    current Realm).
      ReadableStream* readable =
          ReadableStream::Deserialize(script_state_, port_for_readable,
                                      /*optimizer=*/nullptr, exception_state);
      if (!readable)
        return nullptr;

      // 2. Let writableRecord be !
      //    StructuredDeserializeWithTransfer(dataHolder.[[writable]], the
      //    current Realm).
      WritableStream* writable =
          WritableStream::Deserialize(script_state_, port_for_writable,
                                      /*optimizer=*/nullptr, exception_state);
      if (!writable)
        return nullptr;

      // 3. Set value.[[readable]] to readableRecord.[[Deserialized]].
      // 4. Set value.[[writable]] to writableRecord.[[Deserialized]].
      // 5. Set value.[[backpressure]], value.[[backpressureChangePromise]], and
      //    value.[[controller]] to undefined.
      return MakeGarbageCollected<TransformStream>(readable, writable);
    }
    case kDOMExceptionTag: {
      // See the serialization side for |stack_unused|.
      String name, message, stack_unused;
      if (!ReadUTF8String(&name) || !ReadUTF8String(&message) ||
          !ReadUTF8String(&stack_unused)) {
        return nullptr;
      }
      // DOMException::Create takes its arguments in the opposite order.
      return DOMException::Create(message, name);
    }
    default:
      break;
  }
  return nullptr;
}

File* V8ScriptValueDeserializer::ReadFile() {
  if (Version() < 3)
    return nullptr;
  String path, name, relative_path, uuid, type;
  uint32_t has_snapshot = 0;
  uint64_t size = 0;
  double last_modified_ms = 0;
  if (!ReadUTF8String(&path) || (Version() >= 4 && !ReadUTF8String(&name)) ||
      (Version() >= 4 && !ReadUTF8String(&relative_path)) ||
      !ReadUTF8String(&uuid) || !ReadUTF8String(&type) ||
      (Version() >= 4 && !ReadUint32(&has_snapshot)))
    return nullptr;
  if (has_snapshot) {
    if (!ReadUint64(&size) || !ReadDouble(&last_modified_ms))
      return nullptr;
    if (Version() < 8)
      last_modified_ms *= kMsPerSecond;
  }
  uint32_t is_user_visible = 1;
  if (Version() >= 7 && !ReadUint32(&is_user_visible))
    return nullptr;
  const File::UserVisibility user_visibility =
      is_user_visible ? File::kIsUserVisible : File::kIsNotUserVisible;
  const uint64_t kSizeForDataHandle = static_cast<uint64_t>(-1);
  auto blob_handle = GetOrCreateBlobDataHandle(uuid, type, kSizeForDataHandle);
  if (!blob_handle)
    return nullptr;
  base::Optional<base::Time> last_modified;
  if (has_snapshot && std::isfinite(last_modified_ms))
    last_modified = base::Time::FromJsTime(last_modified_ms);
  return File::CreateFromSerialization(path, name, relative_path,
                                       user_visibility, has_snapshot, size,
                                       last_modified, std::move(blob_handle));
}

File* V8ScriptValueDeserializer::ReadFileIndex() {
  if (Version() < 6 || !blob_info_array_)
    return nullptr;
  uint32_t index;
  if (!ReadUint32(&index) || index >= blob_info_array_->size())
    return nullptr;
  const WebBlobInfo& info = (*blob_info_array_)[index];
  auto blob_handle = info.GetBlobHandle();
  if (!blob_handle) {
    blob_handle =
        GetOrCreateBlobDataHandle(info.Uuid(), info.GetType(), info.size());
  }
  if (!blob_handle)
    return nullptr;
  return File::CreateFromIndexedSerialization(info.FileName(), info.size(),
                                              info.LastModified(), blob_handle);
}

DOMRectReadOnly* V8ScriptValueDeserializer::ReadDOMRectReadOnly() {
  double x = 0, y = 0, width = 0, height = 0;
  if (!ReadDouble(&x) || !ReadDouble(&y) || !ReadDouble(&width) ||
      !ReadDouble(&height))
    return nullptr;
  return DOMRectReadOnly::Create(x, y, width, height);
}

scoped_refptr<BlobDataHandle>
V8ScriptValueDeserializer::GetOrCreateBlobDataHandle(const String& uuid,
                                                     const String& type,
                                                     uint64_t size) {
  // The containing ssv may have a BDH for this uuid if this ssv is just being
  // passed from main to worker thread (for example). We use those values when
  // creating the new blob instead of cons'ing up a new BDH.
  //
  // FIXME: Maybe we should require that it work that way where the ssv must
  // have a BDH for any blobs it comes across during deserialization. Would
  // require callers to explicitly populate the collection of BDH's for blobs to
  // work, which would encourage lifetimes to be considered when passing ssv's
  // around cross process. At present, we get 'lucky' in some cases because the
  // blob in the src process happens to still exist at the time the dest process
  // is deserializing.
  // For example in sharedWorker.postMessage(...).
  BlobDataHandleMap& handles = serialized_script_value_->BlobDataHandles();
  BlobDataHandleMap::const_iterator it = handles.find(uuid);
  if (it != handles.end())
    return it->value;
  // Creating a BlobDataHandle from an empty string will get this renderer
  // killed, so since we're parsing untrusted data (from possibly another
  // process/renderer) return null instead.
  if (uuid.IsEmpty())
    return nullptr;
  return BlobDataHandle::Create(uuid, type, size);
}

v8::MaybeLocal<v8::Object> V8ScriptValueDeserializer::ReadHostObject(
    v8::Isolate* isolate) {
  DCHECK_EQ(isolate, script_state_->GetIsolate());
  ExceptionState exception_state(isolate, ExceptionState::kUnknownContext,
                                 nullptr, nullptr);
  ScriptWrappable* wrappable = nullptr;
  SerializationTag tag = kVersionTag;
  if (ReadTag(&tag)) {
    wrappable = ReadDOMObject(tag, exception_state);
    if (exception_state.HadException())
      return v8::MaybeLocal<v8::Object>();
  }
  if (!wrappable) {
    exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError,
                                      "Unable to deserialize cloned data.");
    return v8::MaybeLocal<v8::Object>();
  }
  v8::Local<v8::Object> creation_context =
      script_state_->GetContext()->Global();
  v8::Local<v8::Value> wrapper = ToV8(wrappable, creation_context, isolate);
  DCHECK(wrapper->IsObject());
  return wrapper.As<v8::Object>();
}

v8::MaybeLocal<v8::WasmModuleObject>
V8ScriptValueDeserializer::GetWasmModuleFromId(v8::Isolate* isolate,
                                               uint32_t id) {
  if (id < serialized_script_value_->WasmModules().size()) {
    ExecutionContext* execution_context = ExecutionContext::From(script_state_);
    DCHECK(serialized_script_value_->origin());
    UseCounter::Count(execution_context, WebFeature::kWasmModuleSharing);
    if (!serialized_script_value_->origin()->IsSameOriginWith(
            execution_context->GetSecurityOrigin())) {
      UseCounter::Count(execution_context,
                        WebFeature::kCrossOriginWasmModuleSharing);
    }
    return v8::WasmModuleObject::FromCompiledModule(
        isolate, serialized_script_value_->WasmModules()[id]);
  }
  CHECK(serialized_script_value_->WasmModules().IsEmpty());
  return v8::MaybeLocal<v8::WasmModuleObject>();
}

v8::MaybeLocal<v8::SharedArrayBuffer>
V8ScriptValueDeserializer::GetSharedArrayBufferFromId(v8::Isolate* isolate,
                                                      uint32_t id) {
  auto& shared_array_buffers_contents =
      serialized_script_value_->SharedArrayBuffersContents();
  if (id < shared_array_buffers_contents.size()) {
    ArrayBufferContents& contents = shared_array_buffers_contents.at(id);
    DOMSharedArrayBuffer* shared_array_buffer =
        DOMSharedArrayBuffer::Create(contents);
    v8::Local<v8::Object> creation_context =
        script_state_->GetContext()->Global();
    v8::Local<v8::Value> wrapper =
        ToV8(shared_array_buffer, creation_context, isolate);
    DCHECK(wrapper->IsSharedArrayBuffer());
    return v8::Local<v8::SharedArrayBuffer>::Cast(wrapper);
  }
  ExceptionState exception_state(isolate, ExceptionState::kUnknownContext,
                                 nullptr, nullptr);
  exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError,
                                    "Unable to deserialize SharedArrayBuffer.");
  // If the id does not map to a valid index, it is expected that the
  // SerializedScriptValue emptied its shared ArrayBufferContents when crossing
  // a process boundary.
  CHECK(shared_array_buffers_contents.IsEmpty());
  return v8::MaybeLocal<v8::SharedArrayBuffer>();
}

bool V8ScriptValueDeserializer::TransferableStreamsEnabled() const {
  return RuntimeEnabledFeatures::TransferableStreamsEnabled(
      ExecutionContext::From(script_state_));
}

}  // namespace blink
