/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_blob_info.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/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_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
#include "third_party/blink/renderer/bindings/modules/v8/to_v8_for_modules.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_any.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_key_path.h"
#include "third_party/blink/renderer/modules/indexeddb/idb_value.h"
#include "third_party/blink/renderer/modules/indexeddb/web_idb_key_path.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/text/string_view.h"

namespace blink {

namespace {

std::unique_ptr<IDBKey> CheckKeyFromValueAndKeyPathInternal(
    v8::Isolate* isolate,
    const ScriptValue& value,
    const String& key_path) {
  IDBKeyPath idb_key_path(key_path);
  EXPECT_TRUE(idb_key_path.IsValid());

  NonThrowableExceptionState exception_state;
  return ScriptValue::To<std::unique_ptr<IDBKey>>(
      isolate, value, exception_state, idb_key_path);
}

void CheckKeyPathNullValue(v8::Isolate* isolate,
                           const ScriptValue& value,
                           const String& key_path) {
  ASSERT_FALSE(CheckKeyFromValueAndKeyPathInternal(isolate, value, key_path));
}

bool InjectKey(ScriptState* script_state,
               IDBKey* key,
               ScriptValue& value,
               const String& key_path) {
  IDBKeyPath idb_key_path(key_path);
  EXPECT_TRUE(idb_key_path.IsValid());
  ScriptValue key_value = ScriptValue::From(script_state, key);
  return InjectV8KeyIntoV8Value(script_state->GetIsolate(), key_value.V8Value(),
                                value.V8Value(), idb_key_path);
}

void CheckInjection(ScriptState* script_state,
                    IDBKey* key,
                    ScriptValue& value,
                    const String& key_path) {
  bool result = InjectKey(script_state, key, value, key_path);
  ASSERT_TRUE(result);
  std::unique_ptr<IDBKey> extracted_key = CheckKeyFromValueAndKeyPathInternal(
      script_state->GetIsolate(), value, key_path);
  EXPECT_TRUE(key->IsEqual(extracted_key.get()));
}

void CheckInjectionIgnored(ScriptState* script_state,
                           IDBKey* key,
                           ScriptValue& value,
                           const String& key_path) {
  bool result = InjectKey(script_state, key, value, key_path);
  ASSERT_TRUE(result);
  std::unique_ptr<IDBKey> extracted_key = CheckKeyFromValueAndKeyPathInternal(
      script_state->GetIsolate(), value, key_path);
  EXPECT_FALSE(key->IsEqual(extracted_key.get()));
}

void CheckInjectionDisallowed(ScriptState* script_state,
                              ScriptValue& value,
                              const String& key_path) {
  const IDBKeyPath idb_key_path(key_path);
  ASSERT_TRUE(idb_key_path.IsValid());
  EXPECT_FALSE(CanInjectIDBKeyIntoScriptValue(script_state->GetIsolate(), value,
                                              idb_key_path));
}

void CheckKeyPathStringValue(v8::Isolate* isolate,
                             const ScriptValue& value,
                             const String& key_path,
                             const String& expected) {
  std::unique_ptr<IDBKey> idb_key =
      CheckKeyFromValueAndKeyPathInternal(isolate, value, key_path);
  ASSERT_TRUE(idb_key);
  ASSERT_EQ(mojom::IDBKeyType::String, idb_key->GetType());
  ASSERT_TRUE(expected == idb_key->GetString());
}

void CheckKeyPathNumberValue(v8::Isolate* isolate,
                             const ScriptValue& value,
                             const String& key_path,
                             int expected) {
  std::unique_ptr<IDBKey> idb_key =
      CheckKeyFromValueAndKeyPathInternal(isolate, value, key_path);
  ASSERT_TRUE(idb_key);
  ASSERT_EQ(mojom::IDBKeyType::Number, idb_key->GetType());
  ASSERT_TRUE(expected == idb_key->Number());
}

// SerializedScriptValue header format offsets are inferred from the Blink and
// V8 serialization code. The code below DCHECKs that
constexpr static size_t kSSVHeaderBlinkVersionTagOffset = 0;
constexpr static size_t kSSVHeaderBlinkVersionOffset = 1;
constexpr static size_t kSSVHeaderV8VersionTagOffset = 2;
// constexpr static size_t kSSVHeaderV8VersionOffset = 3;

// Follows the same steps as the IndexedDB value serialization code.
void SerializeV8Value(v8::Local<v8::Value> value,
                      v8::Isolate* isolate,
                      Vector<char>* wire_bytes) {
  NonThrowableExceptionState non_throwable_exception_state;

  SerializedScriptValue::SerializeOptions options;
  scoped_refptr<SerializedScriptValue> serialized_value =
      SerializedScriptValue::Serialize(isolate, value, options,
                                       non_throwable_exception_state);
  base::span<const uint8_t> ssv_wire_data = serialized_value->GetWireData();
  DCHECK(wire_bytes->IsEmpty());
  wire_bytes->Append(ssv_wire_data.data(),
                     static_cast<wtf_size_t>(ssv_wire_data.size()));

  // Sanity check that the serialization header has not changed, as the tests
  // that use this method rely on the header format.
  //
  // The cast from char* to unsigned char* is necessary to avoid VS2015 warning
  // C4309 (truncation of constant value). This happens because VersionTag is
  // 0xFF.
  const unsigned char* wire_data =
      reinterpret_cast<unsigned char*>(wire_bytes->data());
  ASSERT_EQ(static_cast<unsigned char>(kVersionTag),
            wire_data[kSSVHeaderBlinkVersionTagOffset]);
  ASSERT_EQ(
      static_cast<unsigned char>(SerializedScriptValue::kWireFormatVersion),
      wire_data[kSSVHeaderBlinkVersionOffset]);

  ASSERT_EQ(static_cast<unsigned char>(kVersionTag),
            wire_data[kSSVHeaderV8VersionTagOffset]);
  // TODO(jbroman): Use the compile-time constant for V8 data format version.
  // ASSERT_EQ(v8::ValueSerializer::GetCurrentDataFormatVersion(),
  //           wire_data[kSSVHeaderV8VersionOffset]);
}

std::unique_ptr<IDBValue> CreateIDBValue(v8::Isolate* isolate,
                                         Vector<char>& wire_bytes,
                                         double primary_key,
                                         const WebString& key_path) {
  WebData web_data(SharedBuffer::AdoptVector(wire_bytes));
  scoped_refptr<SharedBuffer> data(web_data);
  std::unique_ptr<IDBValue> value =
      IDBValue::Create(data, Vector<WebBlobInfo>());
  value->SetInjectedPrimaryKey(IDBKey::CreateNumber(primary_key),
                               WebIDBKeyPath(key_path));

  value->SetIsolate(isolate);
  return value;
}

TEST(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyStringValue) {
  V8TestingScope scope;
  v8::Isolate* isolate = scope.GetIsolate();

  // object = { foo: "zoo" }
  ScriptValue script_value = V8ObjectBuilder(scope.GetScriptState())
                                 .Add("foo", "zoo")
                                 .GetScriptValue();
  CheckKeyPathStringValue(isolate, script_value, "foo", "zoo");
  CheckKeyPathNullValue(isolate, script_value, "bar");
}

}  // namespace

TEST(IDBKeyFromValueAndKeyPathTest, TopLevelPropertyNumberValue) {
  V8TestingScope scope;
  v8::Isolate* isolate = scope.GetIsolate();

  // object = { foo: 456 }
  ScriptValue script_value = V8ObjectBuilder(scope.GetScriptState())
                                 .AddNumber("foo", 456)
                                 .GetScriptValue();
  CheckKeyPathNumberValue(isolate, script_value, "foo", 456);
  CheckKeyPathNullValue(isolate, script_value, "bar");
}

TEST(IDBKeyFromValueAndKeyPathTest, SubProperty) {
  V8TestingScope scope;
  ScriptState* script_state = scope.GetScriptState();
  v8::Isolate* isolate = scope.GetIsolate();

  // object = { foo: { bar: "zee" } }
  ScriptValue script_value =
      V8ObjectBuilder(script_state)
          .Add("foo", V8ObjectBuilder(script_state).Add("bar", "zee"))
          .GetScriptValue();
  CheckKeyPathStringValue(isolate, script_value, "foo.bar", "zee");
  CheckKeyPathNullValue(isolate, script_value, "bar");
}

TEST(InjectIDBKeyTest, ImplicitValues) {
  V8TestingScope scope;
  v8::Isolate* isolate = scope.GetIsolate();
  {
    v8::Local<v8::String> string = V8String(isolate, "string");
    ScriptValue value = ScriptValue(scope.GetScriptState(), string);
    std::unique_ptr<IDBKey> idb_key = IDBKey::CreateNumber(123);
    CheckInjectionIgnored(scope.GetScriptState(), idb_key.get(), value,
                          "length");
  }
  {
    v8::Local<v8::Array> array = v8::Array::New(isolate);
    ScriptValue value = ScriptValue(scope.GetScriptState(), array);
    std::unique_ptr<IDBKey> idb_key = IDBKey::CreateNumber(456);
    CheckInjectionIgnored(scope.GetScriptState(), idb_key.get(), value,
                          "length");
  }
}

TEST(InjectIDBKeyTest, TopLevelPropertyStringValue) {
  V8TestingScope scope;

  // object = { foo: "zoo" }
  ScriptValue script_object = V8ObjectBuilder(scope.GetScriptState())
                                  .Add("foo", "zoo")
                                  .GetScriptValue();
  std::unique_ptr<IDBKey> idb_string_key = IDBKey::CreateString("myNewKey");
  CheckInjection(scope.GetScriptState(), idb_string_key.get(), script_object,
                 "bar");
  std::unique_ptr<IDBKey> idb_number_key = IDBKey::CreateNumber(1234);
  CheckInjection(scope.GetScriptState(), idb_number_key.get(), script_object,
                 "bar");

  CheckInjectionDisallowed(scope.GetScriptState(), script_object, "foo.bar");
}

TEST(InjectIDBKeyTest, SubProperty) {
  V8TestingScope scope;
  ScriptState* script_state = scope.GetScriptState();

  // object = { foo: { bar: "zee" } }
  ScriptValue script_object =
      V8ObjectBuilder(script_state)
          .Add("foo", V8ObjectBuilder(script_state).Add("bar", "zee"))
          .GetScriptValue();

  std::unique_ptr<IDBKey> idb_string_key = IDBKey::CreateString("myNewKey");
  CheckInjection(scope.GetScriptState(), idb_string_key.get(), script_object,
                 "foo.baz");
  std::unique_ptr<IDBKey> idb_number_key = IDBKey::CreateNumber(789);
  CheckInjection(scope.GetScriptState(), idb_number_key.get(), script_object,
                 "foo.baz");
  std::unique_ptr<IDBKey> idb_date_key = IDBKey::CreateDate(4567);
  CheckInjection(scope.GetScriptState(), idb_date_key.get(), script_object,
                 "foo.baz");
  CheckInjection(scope.GetScriptState(), idb_date_key.get(), script_object,
                 "bar");
  std::unique_ptr<IDBKey> idb_array_key =
      IDBKey::CreateArray(IDBKey::KeyArray());
  CheckInjection(scope.GetScriptState(), idb_array_key.get(), script_object,
                 "foo.baz");
  CheckInjection(scope.GetScriptState(), idb_array_key.get(), script_object,
                 "bar");

  CheckInjectionDisallowed(scope.GetScriptState(), script_object,
                           "foo.bar.baz");
  std::unique_ptr<IDBKey> idb_zoo_key = IDBKey::CreateString("zoo");
  CheckInjection(scope.GetScriptState(), idb_zoo_key.get(), script_object,
                 "foo.xyz.foo");
}

TEST(DeserializeIDBValueTest, CurrentVersions) {
  V8TestingScope scope;
  v8::Isolate* isolate = scope.GetIsolate();

  Vector<char> object_bytes;
  v8::Local<v8::Object> empty_object = v8::Object::New(isolate);
  SerializeV8Value(empty_object, isolate, &object_bytes);
  std::unique_ptr<IDBValue> idb_value =
      CreateIDBValue(isolate, object_bytes, 42.0, "foo");

  v8::Local<v8::Value> v8_value = DeserializeIDBValue(
      isolate, scope.GetContext()->Global(), idb_value.get());
  EXPECT_TRUE(!scope.GetExceptionState().HadException());

  ASSERT_TRUE(v8_value->IsObject());
  v8::Local<v8::Object> v8_value_object = v8_value.As<v8::Object>();
  v8::Local<v8::Value> v8_number_value =
      v8_value_object->Get(scope.GetContext(), V8AtomicString(isolate, "foo"))
          .ToLocalChecked();
  ASSERT_TRUE(v8_number_value->IsNumber());
  v8::Local<v8::Number> v8_number = v8_number_value.As<v8::Number>();
  EXPECT_EQ(v8_number->Value(), 42.0);
}

TEST(DeserializeIDBValueTest, FutureV8Version) {
  V8TestingScope scope;
  v8::Isolate* isolate = scope.GetIsolate();

  // Pretend that the object was serialized by a future version of V8.
  Vector<char> object_bytes;
  v8::Local<v8::Object> empty_object = v8::Object::New(isolate);
  SerializeV8Value(empty_object, isolate, &object_bytes);
  object_bytes[kSSVHeaderV8VersionTagOffset] += 1;

  // The call sequence below mimics IndexedDB's usage pattern when attempting to
  // read a value in an object store with a key generator and a key path, but
  // the serialized value uses a newer format version.
  //
  // http://crbug.com/703704 has a reproduction for this test's circumstances.
  std::unique_ptr<IDBValue> idb_value =
      CreateIDBValue(isolate, object_bytes, 42.0, "foo");

  v8::Local<v8::Value> v8_value = DeserializeIDBValue(
      isolate, scope.GetContext()->Global(), idb_value.get());
  EXPECT_TRUE(!scope.GetExceptionState().HadException());
  EXPECT_TRUE(v8_value->IsNull());
}

TEST(DeserializeIDBValueTest, InjectionIntoNonObject) {
  V8TestingScope scope;
  v8::Isolate* isolate = scope.GetIsolate();

  // Simulate a storage corruption where an object is read back as a number.
  // This test uses a one-segment key path.
  Vector<char> object_bytes;
  v8::Local<v8::Number> number = v8::Number::New(isolate, 42.0);
  SerializeV8Value(number, isolate, &object_bytes);
  std::unique_ptr<IDBValue> idb_value =
      CreateIDBValue(isolate, object_bytes, 42.0, "foo");

  v8::Local<v8::Value> v8_value = DeserializeIDBValue(
      isolate, scope.GetContext()->Global(), idb_value.get());
  EXPECT_TRUE(!scope.GetExceptionState().HadException());
  ASSERT_TRUE(v8_value->IsNumber());
  v8::Local<v8::Number> v8_number = v8_value.As<v8::Number>();
  EXPECT_EQ(v8_number->Value(), 42.0);
}

TEST(DeserializeIDBValueTest, NestedInjectionIntoNonObject) {
  V8TestingScope scope;
  v8::Isolate* isolate = scope.GetIsolate();

  // Simulate a storage corruption where an object is read back as a number.
  // This test uses a multiple-segment key path.
  Vector<char> object_bytes;
  v8::Local<v8::Number> number = v8::Number::New(isolate, 42.0);
  SerializeV8Value(number, isolate, &object_bytes);
  std::unique_ptr<IDBValue> idb_value =
      CreateIDBValue(isolate, object_bytes, 42.0, "foo.bar");

  v8::Local<v8::Value> v8_value = DeserializeIDBValue(
      isolate, scope.GetContext()->Global(), idb_value.get());
  EXPECT_TRUE(!scope.GetExceptionState().HadException());
  ASSERT_TRUE(v8_value->IsNumber());
  v8::Local<v8::Number> v8_number = v8_value.As<v8::Number>();
  EXPECT_EQ(v8_number->Value(), 42.0);
}

}  // namespace blink
