// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Tests effects of (CSP) "unsafe-eval" and "wasm-eval" callback functions.
//
// Note: These tests are in a separate test file because the tests dynamically
// change the isolate in terms of callbacks allow_code_gen_callback and
// allow_wasm_code_gen_callback.

#include "src/api/api-inl.h"
#include "src/wasm/wasm-module-builder.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-objects.h"

#include "test/cctest/cctest.h"
#include "test/common/wasm/wasm-module-runner.h"

namespace v8 {
namespace internal {
namespace wasm {

namespace {

// Possible values for callback pointers.
enum TestValue {
  kTestUsingNull,   // no callback.
  kTestUsingFalse,  // callback returning false.
  kTestUsingTrue,   // callbacl returning true.
};

constexpr int kNumTestValues = 3;

const char* TestValueName[kNumTestValues] = {"null", "false", "true"};

// Defined to simplify iterating over TestValues;
const TestValue AllTestValues[kNumTestValues] = {
    kTestUsingNull, kTestUsingFalse, kTestUsingTrue};

// This matrix holds the results of setting allow_code_gen_callback
// (first index) and allow_wasm_code_gen_callback (second index) using
// TestValue's. The value in the matrix is true if compilation is
// allowed, and false otherwise.
const bool ExpectedResults[kNumTestValues][kNumTestValues] = {
    {true, false, true}, {false, false, true}, {true, false, true}};

bool TrueCallback(Local<v8::Context>, Local<v8::String>) { return true; }

bool FalseCallback(Local<v8::Context>, Local<v8::String>) { return false; }

using CallbackFn = bool (*)(Local<v8::Context>, Local<v8::String>);

// Defines the Callback to use for the corresponding TestValue.
CallbackFn Callback[kNumTestValues] = {nullptr, FalseCallback, TrueCallback};

void BuildTrivialModule(Zone* zone, ZoneBuffer* buffer) {
  WasmModuleBuilder* builder = zone->New<WasmModuleBuilder>(zone);
  builder->WriteTo(buffer);
}

bool TestModule(Isolate* isolate, v8::MemorySpan<const uint8_t> wire_bytes) {
  HandleScope scope(isolate);
  v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
  v8::Local<v8::Context> context =
      Utils::ToLocal(Handle<Context>::cast(isolate->native_context()));

  // Get the "WebAssembly.Module" function.
  auto get_property = [context, v8_isolate](
                          v8::Local<v8::Object> obj,
                          const char* property_name) -> v8::Local<v8::Object> {
    auto name = v8::String::NewFromUtf8(v8_isolate, property_name,
                                        NewStringType::kInternalized)
                    .ToLocalChecked();
    return obj->Get(context, name).ToLocalChecked().As<v8::Object>();
  };
  auto wasm_class = get_property(context->Global(), "WebAssembly");
  auto module_class = get_property(wasm_class, "Module");

  // Create an arraybuffer with the wire bytes.
  v8::Local<v8::ArrayBuffer> buf =
      v8::ArrayBuffer::New(v8_isolate, wire_bytes.size());
  memcpy(static_cast<uint8_t*>(buf->GetBackingStore()->Data()),
         wire_bytes.data(), wire_bytes.size());

  // Now call the "WebAssembly.Module" function with the array buffer. Return
  // true if this succeeded, false otherwise.
  v8::TryCatch try_catch(v8_isolate);
  v8::Local<v8::Value> args[] = {buf};
  MaybeLocal<Value> module_object =
      module_class->CallAsConstructor(context, arraysize(args), args);

  CHECK_EQ(try_catch.HasCaught(), module_object.IsEmpty());
  return !module_object.IsEmpty();
}

}  // namespace

TEST(PropertiesOfCodegenCallbacks) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  ZoneBuffer buffer(&zone);
  BuildTrivialModule(&zone, &buffer);
  v8::MemorySpan<const uint8_t> wire_bytes = {buffer.begin(), buffer.size()};
  Isolate* isolate = CcTest::InitIsolateOnce();
  HandleScope scope(isolate);

  for (TestValue codegen : AllTestValues) {
    for (TestValue wasm_codegen : AllTestValues) {
      fprintf(stderr, "Test codegen = %s, wasm_codegen = %s\n",
              TestValueName[codegen], TestValueName[wasm_codegen]);
      isolate->set_allow_code_gen_callback(Callback[codegen]);
      isolate->set_allow_wasm_code_gen_callback(Callback[wasm_codegen]);
      bool found = TestModule(isolate, wire_bytes);
      bool expected = ExpectedResults[codegen][wasm_codegen];
      CHECK_EQ(expected, found);
      CcTest::CollectAllAvailableGarbage();
    }
  }
}

TEST(WasmModuleObjectCompileFailure) {
  const uint8_t wire_bytes_arr[] = {0xDE, 0xAD, 0xBE, 0xEF};
  v8::MemorySpan<const uint8_t> wire_bytes = {wire_bytes_arr,
                                              arraysize(wire_bytes_arr)};
  Isolate* isolate = CcTest::InitIsolateOnce();
  HandleScope scope(isolate);
  CHECK(!TestModule(isolate, wire_bytes));
}

}  // namespace wasm
}  // namespace internal
}  // namespace v8
