// Copyright (c) 2012 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 "content/child/v8_value_converter_impl.h"

#include <stddef.h>
#include <stdint.h>

#include <cmath>
#include <memory>

#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/test/values_test_util.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "v8/include/v8.h"

namespace content {

// To improve the performance of
// V8ValueConverterImpl::UpdateAndCheckUniqueness, identity hashes of objects
// are used during checking for duplicates. For testing purposes we need to
// ignore the hash sometimes. Create this helper object to avoid using identity
// hashes for the lifetime of the helper.
class ScopedAvoidIdentityHashForTesting {
 public:
  // The hashes will be ignored in |converter|, which must not be NULL and it
  // must outlive the created instance of this helper.
  explicit ScopedAvoidIdentityHashForTesting(
      content::V8ValueConverterImpl* converter);
  ~ScopedAvoidIdentityHashForTesting();

 private:
  content::V8ValueConverterImpl* converter_;

  DISALLOW_COPY_AND_ASSIGN(ScopedAvoidIdentityHashForTesting);
};

ScopedAvoidIdentityHashForTesting::ScopedAvoidIdentityHashForTesting(
    content::V8ValueConverterImpl* converter)
    : converter_(converter) {
  CHECK(converter_);
  converter_->avoid_identity_hash_for_testing_ = true;
}

ScopedAvoidIdentityHashForTesting::~ScopedAvoidIdentityHashForTesting() {
  converter_->avoid_identity_hash_for_testing_ = false;
}

class V8ValueConverterImplTest : public testing::Test {
 public:
  V8ValueConverterImplTest()
      : isolate_(v8::Isolate::GetCurrent()) {
  }

 protected:
  void SetUp() override {
    v8::HandleScope handle_scope(isolate_);
    v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_);
    context_.Reset(isolate_, v8::Context::New(isolate_, NULL, global));
  }

  void TearDown() override { context_.Reset(); }

  std::string GetString(base::DictionaryValue* value, const std::string& key) {
    std::string temp;
    if (!value->GetString(key, &temp)) {
      ADD_FAILURE();
      return std::string();
    }
    return temp;
  }

  std::string GetString(v8::Local<v8::Object> value, const std::string& key) {
    v8::Local<v8::String> temp =
        value->Get(v8::String::NewFromUtf8(isolate_, key.c_str()))
            .As<v8::String>();
    if (temp.IsEmpty()) {
      ADD_FAILURE();
      return std::string();
    }
    v8::String::Utf8Value utf8(temp);
    return std::string(*utf8, utf8.length());
  }

  std::string GetString(base::ListValue* value, uint32_t index) {
    std::string temp;
    if (!value->GetString(static_cast<size_t>(index), &temp)) {
      ADD_FAILURE();
      return std::string();
    }
    return temp;
  }

  std::string GetString(v8::Local<v8::Array> value, uint32_t index) {
    v8::Local<v8::String> temp = value->Get(index).As<v8::String>();
    if (temp.IsEmpty()) {
      ADD_FAILURE();
      return std::string();
    }
    v8::String::Utf8Value utf8(temp);
    return std::string(*utf8, utf8.length());
  }

  int32_t GetInt(v8::Local<v8::Object> value, const std::string& key) {
    v8::Local<v8::Int32> temp =
        value->Get(v8::String::NewFromUtf8(isolate_, key.c_str()))
            .As<v8::Int32>();
    if (temp.IsEmpty()) {
      ADD_FAILURE();
      return -1;
    }
    return temp->Value();
  }

  int32_t GetInt(v8::Local<v8::Object> value, uint32_t index) {
    v8::Local<v8::Int32> temp = value->Get(index).As<v8::Int32>();
    if (temp.IsEmpty()) {
      ADD_FAILURE();
      return -1;
    }
    return temp->Value();
  }

  bool IsNull(base::DictionaryValue* value, const std::string& key) {
    base::Value* child = NULL;
    if (!value->Get(key, &child)) {
      ADD_FAILURE();
      return false;
    }
    return child->GetType() == base::Value::TYPE_NULL;
  }

  bool IsNull(v8::Local<v8::Object> value, const std::string& key) {
    v8::Local<v8::Value> child =
        value->Get(v8::String::NewFromUtf8(isolate_, key.c_str()));
    if (child.IsEmpty()) {
      ADD_FAILURE();
      return false;
    }
    return child->IsNull();
  }

  bool IsNull(base::ListValue* value, uint32_t index) {
    base::Value* child = NULL;
    if (!value->Get(static_cast<size_t>(index), &child)) {
      ADD_FAILURE();
      return false;
    }
    return child->GetType() == base::Value::TYPE_NULL;
  }

  bool IsNull(v8::Local<v8::Array> value, uint32_t index) {
    v8::Local<v8::Value> child = value->Get(index);
    if (child.IsEmpty()) {
      ADD_FAILURE();
      return false;
    }
    return child->IsNull();
  }

  void TestWeirdType(const V8ValueConverterImpl& converter,
                     v8::Local<v8::Value> val,
                     base::Value::Type expected_type,
                     std::unique_ptr<base::Value> expected_value) {
    v8::Local<v8::Context> context =
        v8::Local<v8::Context>::New(isolate_, context_);
    std::unique_ptr<base::Value> raw(converter.FromV8Value(val, context));

    if (expected_value) {
      ASSERT_TRUE(raw.get());
      EXPECT_TRUE(expected_value->Equals(raw.get()));
      EXPECT_EQ(expected_type, raw->GetType());
    } else {
      EXPECT_FALSE(raw.get());
    }

    v8::Local<v8::Object> object(v8::Object::New(isolate_));
    object->Set(v8::String::NewFromUtf8(isolate_, "test"), val);
    std::unique_ptr<base::DictionaryValue> dictionary(
        base::DictionaryValue::From(converter.FromV8Value(object, context)));
    ASSERT_TRUE(dictionary.get());

    if (expected_value) {
      base::Value* temp = NULL;
      ASSERT_TRUE(dictionary->Get("test", &temp));
      EXPECT_EQ(expected_type, temp->GetType());
      EXPECT_TRUE(expected_value->Equals(temp));
    } else {
      EXPECT_FALSE(dictionary->HasKey("test"));
    }

    v8::Local<v8::Array> array(v8::Array::New(isolate_));
    array->Set(0, val);
    std::unique_ptr<base::ListValue> list(
        base::ListValue::From(converter.FromV8Value(array, context)));
    ASSERT_TRUE(list.get());
    if (expected_value) {
      base::Value* temp = NULL;
      ASSERT_TRUE(list->Get(0, &temp));
      EXPECT_EQ(expected_type, temp->GetType());
      EXPECT_TRUE(expected_value->Equals(temp));
    } else {
      // Arrays should preserve their length, and convert unconvertible
      // types into null.
      base::Value* temp = NULL;
      ASSERT_TRUE(list->Get(0, &temp));
      EXPECT_EQ(base::Value::TYPE_NULL, temp->GetType());
    }
  }

  v8::Isolate* isolate_;

  // Context for the JavaScript in the test.
  v8::Persistent<v8::Context> context_;
};

TEST_F(V8ValueConverterImplTest, BasicRoundTrip) {
  std::unique_ptr<base::Value> original_root = base::test::ParseJson(
      "{ \n"
      "  \"null\": null, \n"
      "  \"true\": true, \n"
      "  \"false\": false, \n"
      "  \"positive-int\": 42, \n"
      "  \"negative-int\": -42, \n"
      "  \"zero\": 0, \n"
      "  \"double\": 88.8, \n"
      "  \"big-integral-double\": 9007199254740992.0, \n"  // 2.0^53
      "  \"string\": \"foobar\", \n"
      "  \"empty-string\": \"\", \n"
      "  \"dictionary\": { \n"
      "    \"foo\": \"bar\",\n"
      "    \"hot\": \"dog\",\n"
      "  }, \n"
      "  \"empty-dictionary\": {}, \n"
      "  \"list\": [ \"monkey\", \"balls\" ], \n"
      "  \"empty-list\": [], \n"
      "}");

  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);

  V8ValueConverterImpl converter;
  v8::Local<v8::Object> v8_object =
      converter.ToV8Value(original_root.get(), context).As<v8::Object>();
  ASSERT_FALSE(v8_object.IsEmpty());

  EXPECT_EQ(static_cast<const base::DictionaryValue&>(*original_root).size(),
            v8_object->GetPropertyNames()->Length());
  EXPECT_TRUE(
      v8_object->Get(v8::String::NewFromUtf8(isolate_, "null"))->IsNull());
  EXPECT_TRUE(
      v8_object->Get(v8::String::NewFromUtf8(isolate_, "true"))->IsTrue());
  EXPECT_TRUE(
      v8_object->Get(v8::String::NewFromUtf8(isolate_, "false"))->IsFalse());
  EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(isolate_, "positive-int"))
                  ->IsInt32());
  EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(isolate_, "negative-int"))
                  ->IsInt32());
  EXPECT_TRUE(
      v8_object->Get(v8::String::NewFromUtf8(isolate_, "zero"))->IsInt32());
  EXPECT_TRUE(
      v8_object->Get(v8::String::NewFromUtf8(isolate_, "double"))->IsNumber());
  EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(
                                 isolate_, "big-integral-double"))->IsNumber());
  EXPECT_TRUE(
      v8_object->Get(v8::String::NewFromUtf8(isolate_, "string"))->IsString());
  EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(isolate_, "empty-string"))
                  ->IsString());
  EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(isolate_, "dictionary"))
                  ->IsObject());
  EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(
                                 isolate_, "empty-dictionary"))->IsObject());
  EXPECT_TRUE(
      v8_object->Get(v8::String::NewFromUtf8(isolate_, "list"))->IsArray());
  EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(isolate_, "empty-list"))
                  ->IsArray());

  std::unique_ptr<base::Value> new_root(
      converter.FromV8Value(v8_object, context));
  EXPECT_NE(original_root.get(), new_root.get());
  EXPECT_TRUE(original_root->Equals(new_root.get()));
}

TEST_F(V8ValueConverterImplTest, KeysWithDots) {
  std::unique_ptr<base::Value> original =
      base::test::ParseJson("{ \"foo.bar\": \"baz\" }");

  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);

  V8ValueConverterImpl converter;
  std::unique_ptr<base::Value> copy(converter.FromV8Value(
      converter.ToV8Value(original.get(), context), context));

  EXPECT_TRUE(original->Equals(copy.get()));
}

TEST_F(V8ValueConverterImplTest, ObjectExceptions) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  v8::MicrotasksScope microtasks(
      isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks);

  // Set up objects to throw when reading or writing 'foo'.
  const char* source =
      "Object.prototype.__defineSetter__('foo', "
      "    function() { throw new Error('muah!'); });"
      "Object.prototype.__defineGetter__('foo', "
      "    function() { throw new Error('muah!'); });";

  v8::Local<v8::Script> script(
      v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
  script->Run();

  v8::Local<v8::Object> object(v8::Object::New(isolate_));
  object->Set(v8::String::NewFromUtf8(isolate_, "bar"),
              v8::String::NewFromUtf8(isolate_, "bar"));

  // Converting from v8 value should replace the foo property with null.
  V8ValueConverterImpl converter;
  std::unique_ptr<base::DictionaryValue> converted(
      base::DictionaryValue::From(converter.FromV8Value(object, context)));
  EXPECT_TRUE(converted.get());
  // http://code.google.com/p/v8/issues/detail?id=1342
  // EXPECT_EQ(2u, converted->size());
  // EXPECT_TRUE(IsNull(converted.get(), "foo"));
  EXPECT_EQ(1u, converted->size());
  EXPECT_EQ("bar", GetString(converted.get(), "bar"));

  // Converting to v8 value should not trigger the setter.
  converted->SetString("foo", "foo");
  v8::Local<v8::Object> copy =
      converter.ToV8Value(converted.get(), context).As<v8::Object>();
  EXPECT_FALSE(copy.IsEmpty());
  EXPECT_EQ(2u, copy->GetPropertyNames()->Length());
  EXPECT_EQ("foo", GetString(copy, "foo"));
  EXPECT_EQ("bar", GetString(copy, "bar"));
}

TEST_F(V8ValueConverterImplTest, ArrayExceptions) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  v8::MicrotasksScope microtasks(
      isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks);

  const char* source = "(function() {"
      "var arr = [];"
      "arr.__defineSetter__(0, "
      "    function() { throw new Error('muah!'); });"
      "arr.__defineGetter__(0, "
      "    function() { throw new Error('muah!'); });"
      "arr[1] = 'bar';"
      "return arr;"
      "})();";

  v8::Local<v8::Script> script(
      v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
  v8::Local<v8::Array> array = script->Run().As<v8::Array>();
  ASSERT_FALSE(array.IsEmpty());

  // Converting from v8 value should replace the first item with null.
  V8ValueConverterImpl converter;
  std::unique_ptr<base::ListValue> converted(
      base::ListValue::From(converter.FromV8Value(array, context)));
  ASSERT_TRUE(converted.get());
  // http://code.google.com/p/v8/issues/detail?id=1342
  EXPECT_EQ(2u, converted->GetSize());
  EXPECT_TRUE(IsNull(converted.get(), 0));

  // Converting to v8 value should not be affected by the getter/setter
  // because the setters/getters are defined on the array instance, not
  // on the Array's prototype.
  converted.reset(static_cast<base::ListValue*>(
      base::test::ParseJson("[ \"foo\", \"bar\" ]").release()));
  v8::Local<v8::Array> copy =
      converter.ToV8Value(converted.get(), context).As<v8::Array>();
  ASSERT_FALSE(copy.IsEmpty());
  EXPECT_EQ(2u, copy->Length());
  EXPECT_EQ("foo", GetString(copy, 0));
  EXPECT_EQ("bar", GetString(copy, 1));
}

TEST_F(V8ValueConverterImplTest, WeirdTypes) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);

  v8::Local<v8::RegExp> regex(v8::RegExp::New(
      v8::String::NewFromUtf8(isolate_, "."), v8::RegExp::kNone));

  V8ValueConverterImpl converter;
  TestWeirdType(converter, v8::Undefined(isolate_),
                base::Value::TYPE_NULL,  // Arbitrary type, result is NULL.
                std::unique_ptr<base::Value>());
  TestWeirdType(converter, v8::Date::New(isolate_, 1000),
                base::Value::TYPE_DICTIONARY,
                std::unique_ptr<base::Value>(new base::DictionaryValue()));
  TestWeirdType(converter, regex, base::Value::TYPE_DICTIONARY,
                std::unique_ptr<base::Value>(new base::DictionaryValue()));

  converter.SetDateAllowed(true);
  TestWeirdType(converter, v8::Date::New(isolate_, 1000),
                base::Value::TYPE_DOUBLE,
                std::unique_ptr<base::Value>(new base::FundamentalValue(1.0)));

  converter.SetRegExpAllowed(true);
  TestWeirdType(converter, regex, base::Value::TYPE_STRING,
                std::unique_ptr<base::Value>(new base::StringValue("/./")));
}

TEST_F(V8ValueConverterImplTest, Prototype) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  v8::MicrotasksScope microtasks(
      isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks);

  const char* source = "(function() {"
      "Object.prototype.foo = 'foo';"
      "return {};"
      "})();";

  v8::Local<v8::Script> script(
      v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
  v8::Local<v8::Object> object = script->Run().As<v8::Object>();
  ASSERT_FALSE(object.IsEmpty());

  V8ValueConverterImpl converter;
  std::unique_ptr<base::DictionaryValue> result(
      base::DictionaryValue::From(converter.FromV8Value(object, context)));
  ASSERT_TRUE(result.get());
  EXPECT_EQ(0u, result->size());
}

TEST_F(V8ValueConverterImplTest, ObjectPrototypeSetter) {
  std::unique_ptr<base::Value> original =
      base::test::ParseJson("{ \"foo\": \"good value\" }");

  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  v8::MicrotasksScope microtasks(isolate_,
                                 v8::MicrotasksScope::kDoNotRunMicrotasks);

  const char* source =
      "var result = { getters: 0, setters: 0 };"
      "Object.defineProperty(Object.prototype, 'foo', {"
      "  get() { ++result.getters; return 'bogus'; },"
      "  set() { ++result.setters; },"
      "});"
      "result;";

  const char* source_sanity =
      "({}).foo = 'Trigger setter';"
      "({}).foo;";

  v8::Local<v8::Script> script(
      v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
  v8::Local<v8::Object> result = script->Run().As<v8::Object>();
  ASSERT_FALSE(result.IsEmpty());

  // Sanity checks: the getters/setters are normally triggered.
  v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source_sanity))->Run();
  EXPECT_EQ(1, GetInt(result, "getters"));
  EXPECT_EQ(1, GetInt(result, "setters"));

  V8ValueConverterImpl converter;
  v8::Local<v8::Object> converted =
      converter.ToV8Value(original.get(), context).As<v8::Object>();
  EXPECT_FALSE(converted.IsEmpty());

  // Getters/setters shouldn't be triggered.
  EXPECT_EQ(1, GetInt(result, "getters"));
  EXPECT_EQ(1, GetInt(result, "setters"));

  EXPECT_EQ(1u, converted->GetPropertyNames()->Length());
  EXPECT_EQ("good value", GetString(converted, "foo"));

  // Getters/setters shouldn't be triggered while accessing existing values.
  EXPECT_EQ(1, GetInt(result, "getters"));
  EXPECT_EQ(1, GetInt(result, "setters"));

  // Repeat the same exercise with a dictionary without the key.
  base::DictionaryValue missing_key_dict;
  missing_key_dict.SetString("otherkey", "hello");
  v8::Local<v8::Object> converted2 =
      converter.ToV8Value(&missing_key_dict, context).As<v8::Object>();
  EXPECT_FALSE(converted2.IsEmpty());

  // Getters/setters shouldn't be triggered.
  EXPECT_EQ(1, GetInt(result, "getters"));
  EXPECT_EQ(1, GetInt(result, "setters"));

  EXPECT_EQ(1u, converted2->GetPropertyNames()->Length());
  EXPECT_EQ("hello", GetString(converted2, "otherkey"));

  // Missing key = should trigger getter upon access.
  EXPECT_EQ("bogus", GetString(converted2, "foo"));
  EXPECT_EQ(2, GetInt(result, "getters"));
  EXPECT_EQ(1, GetInt(result, "setters"));
}

TEST_F(V8ValueConverterImplTest, ArrayPrototypeSetter) {
  std::unique_ptr<base::Value> original =
      base::test::ParseJson("[100, 200, 300]");

  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  v8::MicrotasksScope microtasks(isolate_,
                                 v8::MicrotasksScope::kDoNotRunMicrotasks);

  const char* source =
      "var result = { getters: 0, setters: 0 };"
      "Object.defineProperty(Array.prototype, '1', {"
      "  get() { ++result.getters; return 1337; },"
      "  set() { ++result.setters; },"
      "});"
      "result;";

  const char* source_sanity =
      "[][1] = 'Trigger setter';"
      "[][1];";

  v8::Local<v8::Script> script(
      v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
  v8::Local<v8::Object> result = script->Run().As<v8::Object>();
  ASSERT_FALSE(result.IsEmpty());

  // Sanity checks: the getters/setters are normally triggered.
  v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source_sanity))->Run();
  EXPECT_EQ(1, GetInt(result, "getters"));
  EXPECT_EQ(1, GetInt(result, "setters"));

  V8ValueConverterImpl converter;
  v8::Local<v8::Array> converted =
      converter.ToV8Value(original.get(), context).As<v8::Array>();
  EXPECT_FALSE(converted.IsEmpty());

  // Getters/setters shouldn't be triggered during the conversion.
  EXPECT_EQ(1, GetInt(result, "getters"));
  EXPECT_EQ(1, GetInt(result, "setters"));

  EXPECT_EQ(3u, converted->Length());
  EXPECT_EQ(100, GetInt(converted, 0));
  EXPECT_EQ(200, GetInt(converted, 1));
  EXPECT_EQ(300, GetInt(converted, 2));

  // Getters/setters shouldn't be triggered while accessing existing values.
  EXPECT_EQ(1, GetInt(result, "getters"));
  EXPECT_EQ(1, GetInt(result, "setters"));

  // Try again, using an array without the index.
  base::ListValue one_item_list;
  one_item_list.AppendInteger(123456);
  v8::Local<v8::Array> converted2 =
      converter.ToV8Value(&one_item_list, context).As<v8::Array>();
  EXPECT_FALSE(converted2.IsEmpty());

  // Getters/setters shouldn't be triggered during the conversion.
  EXPECT_EQ(1, GetInt(result, "getters"));
  EXPECT_EQ(1, GetInt(result, "setters"));

  EXPECT_EQ(1u, converted2->Length());
  EXPECT_EQ(123456, GetInt(converted2, 0));

  // Accessing missing index 1 triggers the getter.
  EXPECT_EQ(1337, GetInt(converted2, 1));
  EXPECT_EQ(2, GetInt(result, "getters"));
  EXPECT_EQ(1, GetInt(result, "setters"));
}

TEST_F(V8ValueConverterImplTest, StripNullFromObjects) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  v8::MicrotasksScope microtasks(
      isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks);

  const char* source = "(function() {"
      "return { foo: undefined, bar: null };"
      "})();";

  v8::Local<v8::Script> script(
      v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
  v8::Local<v8::Object> object = script->Run().As<v8::Object>();
  ASSERT_FALSE(object.IsEmpty());

  V8ValueConverterImpl converter;
  converter.SetStripNullFromObjects(true);

  std::unique_ptr<base::DictionaryValue> result(
      base::DictionaryValue::From(converter.FromV8Value(object, context)));
  ASSERT_TRUE(result.get());
  EXPECT_EQ(0u, result->size());
}

TEST_F(V8ValueConverterImplTest, RecursiveObjects) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);

  V8ValueConverterImpl converter;

  v8::Local<v8::Object> object = v8::Object::New(isolate_).As<v8::Object>();
  ASSERT_FALSE(object.IsEmpty());
  object->Set(v8::String::NewFromUtf8(isolate_, "foo"),
              v8::String::NewFromUtf8(isolate_, "bar"));
  object->Set(v8::String::NewFromUtf8(isolate_, "obj"), object);

  std::unique_ptr<base::DictionaryValue> object_result(
      base::DictionaryValue::From(converter.FromV8Value(object, context)));
  ASSERT_TRUE(object_result.get());
  EXPECT_EQ(2u, object_result->size());
  EXPECT_TRUE(IsNull(object_result.get(), "obj"));

  v8::Local<v8::Array> array = v8::Array::New(isolate_).As<v8::Array>();
  ASSERT_FALSE(array.IsEmpty());
  array->Set(0, v8::String::NewFromUtf8(isolate_, "1"));
  array->Set(1, array);

  std::unique_ptr<base::ListValue> list_result(
      base::ListValue::From(converter.FromV8Value(array, context)));
  ASSERT_TRUE(list_result.get());
  EXPECT_EQ(2u, list_result->GetSize());
  EXPECT_TRUE(IsNull(list_result.get(), 1));
}

TEST_F(V8ValueConverterImplTest, WeirdProperties) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  v8::MicrotasksScope microtasks(
      isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks);

  const char* source = "(function() {"
      "return {"
        "1: 'foo',"
        "'2': 'bar',"
        "true: 'baz',"
        "false: 'qux',"
        "null: 'quux',"
        "undefined: 'oops'"
      "};"
      "})();";

  v8::Local<v8::Script> script(
      v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
  v8::Local<v8::Object> object = script->Run().As<v8::Object>();
  ASSERT_FALSE(object.IsEmpty());

  V8ValueConverterImpl converter;
  std::unique_ptr<base::Value> actual(converter.FromV8Value(object, context));

  std::unique_ptr<base::Value> expected = base::test::ParseJson(
      "{ \n"
      "  \"1\": \"foo\", \n"
      "  \"2\": \"bar\", \n"
      "  \"true\": \"baz\", \n"
      "  \"false\": \"qux\", \n"
      "  \"null\": \"quux\", \n"
      "  \"undefined\": \"oops\", \n"
      "}");

  EXPECT_TRUE(expected->Equals(actual.get()));
}

TEST_F(V8ValueConverterImplTest, ArrayGetters) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  v8::MicrotasksScope microtasks(
      isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks);

  const char* source = "(function() {"
      "var a = [0];"
      "a.__defineGetter__(1, function() { return 'bar'; });"
      "return a;"
      "})();";

  v8::Local<v8::Script> script(
      v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
  v8::Local<v8::Array> array = script->Run().As<v8::Array>();
  ASSERT_FALSE(array.IsEmpty());

  V8ValueConverterImpl converter;
  std::unique_ptr<base::ListValue> result(
      base::ListValue::From(converter.FromV8Value(array, context)));
  ASSERT_TRUE(result.get());
  EXPECT_EQ(2u, result->GetSize());
}

TEST_F(V8ValueConverterImplTest, UndefinedValueBehavior) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  v8::MicrotasksScope microtasks(
      isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks);

  v8::Local<v8::Object> object;
  {
    const char* source = "(function() {"
        "return { foo: undefined, bar: null, baz: function(){} };"
        "})();";
    v8::Local<v8::Script> script(
        v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
    object = script->Run().As<v8::Object>();
    ASSERT_FALSE(object.IsEmpty());
  }

  v8::Local<v8::Array> array;
  {
    const char* source = "(function() {"
        "return [ undefined, null, function(){} ];"
        "})();";
    v8::Local<v8::Script> script(
        v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
    array = script->Run().As<v8::Array>();
    ASSERT_FALSE(array.IsEmpty());
  }

  v8::Local<v8::Array> sparse_array;
  {
    const char* source = "(function() {"
        "return new Array(3);"
        "})();";
    v8::Local<v8::Script> script(
        v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
    sparse_array = script->Run().As<v8::Array>();
    ASSERT_FALSE(sparse_array.IsEmpty());
  }

  V8ValueConverterImpl converter;

  std::unique_ptr<base::Value> actual_object(
      converter.FromV8Value(object, context));
  EXPECT_TRUE(base::Value::Equals(
      base::test::ParseJson("{ \"bar\": null }").get(), actual_object.get()));

  // Everything is null because JSON stringification preserves array length.
  std::unique_ptr<base::Value> actual_array(
      converter.FromV8Value(array, context));
  EXPECT_TRUE(base::Value::Equals(
      base::test::ParseJson("[ null, null, null ]").get(), actual_array.get()));

  std::unique_ptr<base::Value> actual_sparse_array(
      converter.FromV8Value(sparse_array, context));
  EXPECT_TRUE(
      base::Value::Equals(base::test::ParseJson("[ null, null, null ]").get(),
                          actual_sparse_array.get()));
}

TEST_F(V8ValueConverterImplTest, ObjectsWithClashingIdentityHash) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  V8ValueConverterImpl converter;

  // We check that the converter checks identity correctly by disabling the
  // optimization of using identity hashes.
  ScopedAvoidIdentityHashForTesting scoped_hash_avoider(&converter);

  // Create the v8::Object to be converted.
  v8::Local<v8::Array> root(v8::Array::New(isolate_, 4));
  root->Set(0, v8::Local<v8::Object>(v8::Object::New(isolate_)));
  root->Set(1, v8::Local<v8::Object>(v8::Object::New(isolate_)));
  root->Set(2, v8::Local<v8::Object>(v8::Array::New(isolate_, 0)));
  root->Set(3, v8::Local<v8::Object>(v8::Array::New(isolate_, 0)));

  // The expected base::Value result.
  std::unique_ptr<base::Value> expected =
      base::test::ParseJson("[{},{},[],[]]");
  ASSERT_TRUE(expected.get());

  // The actual result.
  std::unique_ptr<base::Value> value(converter.FromV8Value(root, context));
  ASSERT_TRUE(value.get());

  EXPECT_TRUE(expected->Equals(value.get()));
}

TEST_F(V8ValueConverterImplTest, DetectCycles) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  V8ValueConverterImpl converter;

  // Create a recursive array.
  v8::Local<v8::Array> recursive_array(v8::Array::New(isolate_, 1));
  recursive_array->Set(0, recursive_array);

  // The first repetition should be trimmed and replaced by a null value.
  base::ListValue expected_list;
  expected_list.Append(base::Value::CreateNullValue());

  // The actual result.
  std::unique_ptr<base::Value> actual_list(
      converter.FromV8Value(recursive_array, context));
  ASSERT_TRUE(actual_list.get());

  EXPECT_TRUE(expected_list.Equals(actual_list.get()));

  // Now create a recursive object
  const std::string key("key");
  v8::Local<v8::Object> recursive_object(v8::Object::New(isolate_));
  v8::TryCatch try_catch(isolate_);
  recursive_object->Set(
      v8::String::NewFromUtf8(
          isolate_, key.c_str(), v8::String::kNormalString, key.length()),
      recursive_object);
  ASSERT_FALSE(try_catch.HasCaught());

  // The first repetition should be trimmed and replaced by a null value.
  base::DictionaryValue expected_dictionary;
  expected_dictionary.Set(key, base::Value::CreateNullValue());

  // The actual result.
  std::unique_ptr<base::Value> actual_dictionary(
      converter.FromV8Value(recursive_object, context));
  ASSERT_TRUE(actual_dictionary.get());

  EXPECT_TRUE(expected_dictionary.Equals(actual_dictionary.get()));
}

// Tests that reused object values with no cycles do not get nullified.
TEST_F(V8ValueConverterImplTest, ReuseObjects) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);
  v8::MicrotasksScope microtasks(
      isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks);
  V8ValueConverterImpl converter;

  // Object with reused values in different keys.
  {
    const char* source = "(function() {"
        "var objA = {key: 'another same value'};"
        "var obj = {one: objA, two: objA};"
        "return obj;"
        "})();";
    v8::Local<v8::Script> script(
        v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
    v8::Local<v8::Object> object = script->Run().As<v8::Object>();
    ASSERT_FALSE(object.IsEmpty());

    // The actual result.
    std::unique_ptr<base::DictionaryValue> result(
        base::DictionaryValue::From(converter.FromV8Value(object, context)));
    ASSERT_TRUE(result.get());
    EXPECT_EQ(2u, result->size());

    {
      base::DictionaryValue* one_dict = nullptr;
      const char* key1 = "one";
      ASSERT_TRUE(result->GetDictionary(key1, &one_dict));
      EXPECT_EQ("another same value", GetString(one_dict, "key"));
    }
    {
      base::DictionaryValue* two_dict = nullptr;
      const char* key2 = "two";
      ASSERT_TRUE(result->GetDictionary(key2, &two_dict));
      EXPECT_EQ("another same value", GetString(two_dict, "key"));
    }
  }

  // Array with reused values.
  {
    const char* source = "(function() {"
        "var objA = {key: 'same value'};"
        "var arr = [objA, objA];"
        "return arr;"
        "})();";
    v8::Local<v8::Script> script(
        v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
    v8::Local<v8::Array> array = script->Run().As<v8::Array>();
    ASSERT_FALSE(array.IsEmpty());

    // The actual result.
    std::unique_ptr<base::ListValue> list_result(
        base::ListValue::From(converter.FromV8Value(array, context)));
    ASSERT_TRUE(list_result.get());
    ASSERT_EQ(2u, list_result->GetSize());
    for (size_t i = 0; i < list_result->GetSize(); ++i) {
      ASSERT_FALSE(IsNull(list_result.get(), i));
      base::DictionaryValue* dict_value = nullptr;
      ASSERT_TRUE(list_result->GetDictionary(0u, &dict_value));
      EXPECT_EQ("same value", GetString(dict_value, "key"));
    }
  }
}

TEST_F(V8ValueConverterImplTest, MaxRecursionDepth) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);

  // Must larger than kMaxRecursionDepth in v8_value_converter_impl.cc.
  int kDepth = 1000;
  const char kKey[] = "key";

  v8::Local<v8::Object> deep_object = v8::Object::New(isolate_);

  v8::Local<v8::Object> leaf = deep_object;
  for (int i = 0; i < kDepth; ++i) {
    v8::Local<v8::Object> new_object = v8::Object::New(isolate_);
    leaf->Set(v8::String::NewFromUtf8(isolate_, kKey), new_object);
    leaf = new_object;
  }

  V8ValueConverterImpl converter;
  std::unique_ptr<base::Value> value(
      converter.FromV8Value(deep_object, context));
  ASSERT_TRUE(value);

  // Expected depth is kMaxRecursionDepth in v8_value_converter_impl.cc.
  int kExpectedDepth = 100;

  base::Value* current = value.get();
  for (int i = 1; i < kExpectedDepth; ++i) {
    base::DictionaryValue* current_as_object = NULL;
    ASSERT_TRUE(current->GetAsDictionary(&current_as_object)) << i;
    ASSERT_TRUE(current_as_object->Get(kKey, &current)) << i;
  }

  // The leaf node shouldn't have any properties.
  base::DictionaryValue empty;
  EXPECT_TRUE(base::Value::Equals(&empty, current)) << *current;
}

class V8ValueConverterOverridingStrategyForTesting
    : public V8ValueConverter::Strategy {
 public:
  V8ValueConverterOverridingStrategyForTesting()
      : reference_value_(NewReferenceValue()) {}
  bool FromV8Object(v8::Local<v8::Object> value,
                    std::unique_ptr<base::Value>* out,
                    v8::Isolate* isolate,
                    const FromV8ValueCallback& callback) const override {
    *out = NewReferenceValue();
    return true;
  }
  bool FromV8Array(v8::Local<v8::Array> value,
                   std::unique_ptr<base::Value>* out,
                   v8::Isolate* isolate,
                   const FromV8ValueCallback& callback) const override {
    *out = NewReferenceValue();
    return true;
  }
  bool FromV8ArrayBuffer(v8::Local<v8::Object> value,
                         std::unique_ptr<base::Value>* out,
                         v8::Isolate* isolate) const override {
    *out = NewReferenceValue();
    return true;
  }
  bool FromV8Number(v8::Local<v8::Number> value,
                    std::unique_ptr<base::Value>* out) const override {
    *out = NewReferenceValue();
    return true;
  }
  bool FromV8Undefined(std::unique_ptr<base::Value>* out) const override {
    *out = NewReferenceValue();
    return true;
  }
  base::Value* reference_value() const { return reference_value_.get(); }

 private:
  static std::unique_ptr<base::Value> NewReferenceValue() {
    return base::MakeUnique<base::StringValue>("strategy");
  }
  std::unique_ptr<base::Value> reference_value_;
};

TEST_F(V8ValueConverterImplTest, StrategyOverrides) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);

  V8ValueConverterImpl converter;
  V8ValueConverterOverridingStrategyForTesting strategy;
  converter.SetStrategy(&strategy);

  v8::Local<v8::Object> object(v8::Object::New(isolate_));
  std::unique_ptr<base::Value> object_value(
      converter.FromV8Value(object, context));
  ASSERT_TRUE(object_value);
  EXPECT_TRUE(
      base::Value::Equals(strategy.reference_value(), object_value.get()));

  v8::Local<v8::Array> array(v8::Array::New(isolate_));
  std::unique_ptr<base::Value> array_value(
      converter.FromV8Value(array, context));
  ASSERT_TRUE(array_value);
  EXPECT_TRUE(
      base::Value::Equals(strategy.reference_value(), array_value.get()));

  v8::Local<v8::ArrayBuffer> array_buffer(v8::ArrayBuffer::New(isolate_, 0));
  std::unique_ptr<base::Value> array_buffer_value(
      converter.FromV8Value(array_buffer, context));
  ASSERT_TRUE(array_buffer_value);
  EXPECT_TRUE(base::Value::Equals(strategy.reference_value(),
                                  array_buffer_value.get()));

  v8::Local<v8::ArrayBufferView> array_buffer_view(
      v8::Uint8Array::New(array_buffer, 0, 0));
  std::unique_ptr<base::Value> array_buffer_view_value(
      converter.FromV8Value(array_buffer_view, context));
  ASSERT_TRUE(array_buffer_view_value);
  EXPECT_TRUE(base::Value::Equals(strategy.reference_value(),
                                  array_buffer_view_value.get()));

  v8::Local<v8::Number> number(v8::Number::New(isolate_, 0.0));
  std::unique_ptr<base::Value> number_value(
      converter.FromV8Value(number, context));
  ASSERT_TRUE(number_value);
  EXPECT_TRUE(
      base::Value::Equals(strategy.reference_value(), number_value.get()));

  v8::Local<v8::Primitive> undefined(v8::Undefined(isolate_));
  std::unique_ptr<base::Value> undefined_value(
      converter.FromV8Value(undefined, context));
  ASSERT_TRUE(undefined_value);
  EXPECT_TRUE(
      base::Value::Equals(strategy.reference_value(), undefined_value.get()));
}

class V8ValueConverterBypassStrategyForTesting
    : public V8ValueConverter::Strategy {
 public:
  bool FromV8Object(v8::Local<v8::Object> value,
                    std::unique_ptr<base::Value>* out,
                    v8::Isolate* isolate,
                    const FromV8ValueCallback& callback) const override {
    return false;
  }
  bool FromV8Array(v8::Local<v8::Array> value,
                   std::unique_ptr<base::Value>* out,
                   v8::Isolate* isolate,
                   const FromV8ValueCallback& callback) const override {
    return false;
  }
  bool FromV8ArrayBuffer(v8::Local<v8::Object> value,
                         std::unique_ptr<base::Value>* out,
                         v8::Isolate* isolate) const override {
    return false;
  }
  bool FromV8Number(v8::Local<v8::Number> value,
                    std::unique_ptr<base::Value>* out) const override {
    return false;
  }
  bool FromV8Undefined(std::unique_ptr<base::Value>* out) const override {
    return false;
  }
};

// Verify that having a strategy that fallbacks to default behaviour
// actually preserves it.
TEST_F(V8ValueConverterImplTest, StrategyBypass) {
  v8::HandleScope handle_scope(isolate_);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(isolate_, context_);
  v8::Context::Scope context_scope(context);

  V8ValueConverterImpl converter;
  V8ValueConverterBypassStrategyForTesting strategy;
  converter.SetStrategy(&strategy);

  v8::Local<v8::Object> object(v8::Object::New(isolate_));
  std::unique_ptr<base::Value> object_value(
      converter.FromV8Value(object, context));
  ASSERT_TRUE(object_value);
  std::unique_ptr<base::Value> reference_object_value(
      base::test::ParseJson("{}"));
  EXPECT_TRUE(
      base::Value::Equals(reference_object_value.get(), object_value.get()));

  v8::Local<v8::Array> array(v8::Array::New(isolate_));
  std::unique_ptr<base::Value> array_value(
      converter.FromV8Value(array, context));
  ASSERT_TRUE(array_value);
  std::unique_ptr<base::Value> reference_array_value(
      base::test::ParseJson("[]"));
  EXPECT_TRUE(
      base::Value::Equals(reference_array_value.get(), array_value.get()));

  // Not testing ArrayBuffers as V8ValueConverter uses blink helpers and
  // this requires having blink to be initialized.

  v8::Local<v8::Number> number(v8::Number::New(isolate_, 0.0));
  std::unique_ptr<base::Value> number_value(
      converter.FromV8Value(number, context));
  ASSERT_TRUE(number_value);
  std::unique_ptr<base::Value> reference_number_value(
      base::test::ParseJson("0"));
  EXPECT_TRUE(
      base::Value::Equals(reference_number_value.get(), number_value.get()));

  v8::Local<v8::Primitive> undefined(v8::Undefined(isolate_));
  std::unique_ptr<base::Value> undefined_value(
      converter.FromV8Value(undefined, context));
  EXPECT_FALSE(undefined_value);
}

}  // namespace content
