// Copyright 2018 The Fuchsia 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 <limits.h>
#include <new>
#include <stddef.h>

#include <lib/fidl/coding.h>
#include <lib/fidl/internal.h>
#include <lib/zx/channel.h>

#include <unittest/unittest.h>
#include <zircon/syscalls.h>

#include "fidl_coded_types.h"
#include "fidl_structs.h"

// Tests that fidl_close_handles correctly closes all handles in a message,
// even if some of them were moved out/malformed/invalid.

namespace fidl {
namespace {

// All sizes in fidl encoding tables are 32 bits. The fidl compiler
// normally enforces this. Check manually in manual tests.
template <typename T, size_t N>
uint32_t ArrayCount(T const (&array)[N]) {
    static_assert(N < UINT32_MAX, "Array is too large!");
    return N;
}

template <typename T, size_t N>
uint32_t ArraySize(T const (&array)[N]) {
    static_assert(sizeof(array) < UINT32_MAX, "Array is too large!");
    return sizeof(array);
}

bool helper_expect_peer_valid(zx_handle_t channel) {
    BEGIN_HELPER;

    const char* foo = "hello";
    EXPECT_EQ(zx_channel_write(channel, 0, foo, 5, nullptr, 0), ZX_OK);

    END_HELPER;
}

bool helper_expect_peer_invalid(zx_handle_t channel) {
    BEGIN_HELPER;

    const char* foo = "hello";
    EXPECT_EQ(zx_channel_write(channel, 0, foo, 5, nullptr, 0), ZX_ERR_PEER_CLOSED);

    END_HELPER;
}

bool close_single_present_handle() {
    BEGIN_TEST;

    zx_handle_t* channel_0 = new zx_handle_t;
    // Capture the extra handle here; it will not be cleaned by fidl_close_handles
    zx::channel channel_1 = {};

    // Unsafely open a channel, which should be closed automatically by fidl_close_handles
    {
        zx_handle_t out0, out1;
        EXPECT_EQ(zx_channel_create(0, &out0, &out1), ZX_OK);
        *channel_0 = out0;
        channel_1 = zx::channel(out1);
    }

    nonnullable_handle_message_layout message = {};
    message.inline_struct.handle = *channel_0;

    EXPECT_TRUE(helper_expect_peer_valid(channel_1.get()));

    const char* error = nullptr;
    auto status = fidl_close_handles(&nonnullable_handle_message_type, &message, &error);

    EXPECT_EQ(status, ZX_OK);
    EXPECT_NULL(error, error);
    EXPECT_TRUE(helper_expect_peer_invalid(channel_1.get()));
    EXPECT_EQ(message.inline_struct.handle, ZX_HANDLE_INVALID);

    delete channel_0;

    END_TEST;
}

bool close_multiple_present_handles_with_some_invalid() {
    BEGIN_TEST;

    zx_handle_t* channels_0 = new zx_handle_t[3];
    // Capture the extra handles here; these will not be cleaned by fidl_close_handles
    zx::channel channels_1[3] = {};

    // Unsafely open a few channels, which should be closed automatically by fidl_close_handles
    for (int i = 0; i < 3; i++) {
        zx_handle_t out0, out1;
        EXPECT_EQ(zx_channel_create(0, &out0, &out1), ZX_OK);
        channels_0[i] = out0;
        channels_1[i] = zx::channel(out1);
    }

    EXPECT_TRUE(helper_expect_peer_valid(channels_1[0].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[1].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[2].get()));

    // Make the second handle invalid
    multiple_nonnullable_handles_message_layout message = {};
    message.inline_struct.handle_0 = channels_0[0];
    message.inline_struct.handle_1 = ZX_HANDLE_INVALID;
    message.inline_struct.handle_2 = channels_0[2];

    const char* error = nullptr;
    auto status = fidl_close_handles(&multiple_nonnullable_handles_message_type, &message, &error);

    // Since the message is invalid, fidl_close_handles will error, but all the handles
    // in the message must still be closed despite the error.
    EXPECT_EQ(status, ZX_ERR_INVALID_ARGS);
    const char expected_error_msg[] = "message is missing a non-nullable handle";
    EXPECT_STR_EQ(expected_error_msg, error, "wrong error msg");

    // Second channel should remain valid, since it was inaccessible to fidl_close_handles
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[0].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[1].get()));
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[2].get()));

    // Handles 0, 2 have been closed; it is now an error to re-close them.
    EXPECT_EQ(zx_handle_close(channels_0[1]), ZX_OK);

    EXPECT_EQ(message.inline_struct.data_0, 0u);
    EXPECT_EQ(message.inline_struct.data_1, 0u);
    EXPECT_EQ(message.inline_struct.data_2, 0u);
    // Handles in the message struct are released.
    EXPECT_EQ(message.inline_struct.handle_0, ZX_HANDLE_INVALID);
    EXPECT_EQ(message.inline_struct.handle_1, ZX_HANDLE_INVALID);
    EXPECT_EQ(message.inline_struct.handle_2, ZX_HANDLE_INVALID);

    delete[] channels_0;

    END_TEST;
}

bool close_array_of_present_handles() {
    BEGIN_TEST;

    zx_handle_t* channels_0 = new zx_handle_t[4];
    // Capture the extra handles here; these will not be cleaned by fidl_close_handles
    zx::channel channels_1[4] = {};

    // Unsafely open a few channels, which should be closed automatically by fidl_close_handles
    for (int i = 0; i < 4; i++) {
        zx_handle_t out0, out1;
        EXPECT_EQ(zx_channel_create(0, &out0, &out1), ZX_OK);
        channels_0[i] = out0;
        channels_1[i] = zx::channel(out1);
    }

    array_of_nonnullable_handles_message_layout message = {};
    for (int i = 0; i < 4; i++) {
        message.inline_struct.handles[i] = channels_0[i];
    }

    EXPECT_TRUE(helper_expect_peer_valid(channels_1[0].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[1].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[2].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[3].get()));

    const char* error = nullptr;
    auto status = fidl_close_handles(&array_of_nonnullable_handles_message_type, &message, &error);

    EXPECT_EQ(status, ZX_OK);
    EXPECT_NULL(error, error);

    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[0].get()));
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[1].get()));
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[2].get()));
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[3].get()));

    // Handles in the message struct are released.
    EXPECT_EQ(message.inline_struct.handles[0], ZX_HANDLE_INVALID);
    EXPECT_EQ(message.inline_struct.handles[1], ZX_HANDLE_INVALID);
    EXPECT_EQ(message.inline_struct.handles[2], ZX_HANDLE_INVALID);
    EXPECT_EQ(message.inline_struct.handles[3], ZX_HANDLE_INVALID);

    delete[] channels_0;

    END_TEST;
}

bool close_out_of_line_array_of_nonnullable_handles() {
    BEGIN_TEST;

    zx_handle_t* channels_0 = new zx_handle_t[4];
    // Capture the extra handles here; these will not be cleaned by fidl_close_handles
    zx::channel channels_1[4] = {};

    // Unsafely open a few channels, which should be closed automatically by fidl_close_handles
    for (int i = 0; i < 4; i++) {
        zx_handle_t out0, out1;
        EXPECT_EQ(zx_channel_create(0, &out0, &out1), ZX_OK);
        channels_0[i] = out0;
        channels_1[i] = zx::channel(out1);
    }

    out_of_line_array_of_nonnullable_handles_message_layout message = {};
    message.inline_struct.maybe_array = &message.data;
    for (int i = 0; i < 4; i++) {
        message.data.handles[i] = channels_0[i];
    }

    EXPECT_TRUE(helper_expect_peer_valid(channels_1[0].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[1].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[2].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[3].get()));

    const char* error = nullptr;
    auto status = fidl_close_handles(&out_of_line_array_of_nonnullable_handles_message_type,
                                     &message, &error);

    EXPECT_EQ(status, ZX_OK);
    EXPECT_NULL(error, error);

    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[0].get()));
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[1].get()));
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[2].get()));
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[3].get()));

    // Handles in the message struct are released.
    EXPECT_EQ(message.data.handles[0], ZX_HANDLE_INVALID);
    EXPECT_EQ(message.data.handles[1], ZX_HANDLE_INVALID);
    EXPECT_EQ(message.data.handles[2], ZX_HANDLE_INVALID);
    EXPECT_EQ(message.data.handles[3], ZX_HANDLE_INVALID);

    delete[] channels_0;

    END_TEST;
}

// This number of handles is guaranteed to not fit in a channel call.
// Nonetheless, they must be closed by fidl_close_handles.
constexpr int kTooBigNumHandles = ZX_CHANNEL_MAX_MSG_HANDLES * 2;

struct unbounded_too_large_nullable_vector_of_handles_inline_data {
    alignas(FIDL_ALIGNMENT)
    fidl_message_header_t header;
    fidl_vector_t vector;
};
struct unbounded_too_large_nullable_vector_of_handles_message_layout {
    alignas(FIDL_ALIGNMENT)
    unbounded_too_large_nullable_vector_of_handles_inline_data inline_struct;
    alignas(FIDL_ALIGNMENT) zx_handle_t handles[kTooBigNumHandles];
};
const fidl_type_t unbounded_too_large_nullable_vector_of_handles =
    fidl_type_t(fidl::FidlCodedVector(&nullable_handle, FIDL_MAX_SIZE, sizeof(zx_handle_t),
                                      fidl::kNullable));
static const ::fidl::FidlStructField unbounded_too_large_nullable_vector_of_handles_fields[] = {
    ::fidl::FidlStructField(
        &unbounded_too_large_nullable_vector_of_handles,
        offsetof(unbounded_too_large_nullable_vector_of_handles_message_layout,
                 inline_struct.vector)),
};
const fidl_type_t unbounded_too_large_nullable_vector_of_handles_message_type =
    fidl_type_t(::fidl::FidlCodedStruct(
        unbounded_too_large_nullable_vector_of_handles_fields,
        ArrayCount(unbounded_too_large_nullable_vector_of_handles_fields),
        sizeof(unbounded_too_large_nullable_vector_of_handles_inline_data),
        "unbounded_too_large_nullable_vector_of_handles_message"));

bool close_present_too_large_nullable_vector_of_handles() {
    BEGIN_TEST;
    zx_handle_t* channels_0 = new zx_handle_t[kTooBigNumHandles];
    // Capture the extra handles here; these will not be cleaned by fidl_close_handles
    zx::channel channels_1[kTooBigNumHandles] = {};

    // Unsafely open a few channels, which should be closed automatically by fidl_close_handles
    for (int i = 0; i < kTooBigNumHandles; i++) {
        zx_handle_t out0, out1;
        EXPECT_EQ(zx_channel_create(0, &out0, &out1), ZX_OK);
        channels_0[i] = out0;
        channels_1[i] = zx::channel(out1);
    }

    unbounded_too_large_nullable_vector_of_handles_message_layout message = {};
    message.inline_struct.vector = fidl_vector_t{kTooBigNumHandles, &message.handles[0]};
    for (int i = 0; i < kTooBigNumHandles; i++) {
        message.handles[i] = channels_0[i];
        EXPECT_TRUE(helper_expect_peer_valid(channels_1[i].get()));
    }

    const char* error = nullptr;
    auto status =
        fidl_close_handles(&unbounded_too_large_nullable_vector_of_handles_message_type,
                           &message,
                           &error);

    EXPECT_EQ(status, ZX_OK);
    EXPECT_NULL(error, error);

    for (int i = 0; i < kTooBigNumHandles; i++) {
        EXPECT_TRUE(helper_expect_peer_invalid(channels_1[i].get()));
    }

    auto message_handles = reinterpret_cast<zx_handle_t*>(message.inline_struct.vector.data);
    for (int i = 0; i < kTooBigNumHandles; i++) {
        EXPECT_EQ(message_handles[i], ZX_HANDLE_INVALID);
    }

    delete[] channels_0;

    END_TEST;
}

BEGIN_TEST_CASE(handles)
RUN_TEST(close_single_present_handle)
RUN_TEST(close_multiple_present_handles_with_some_invalid)
END_TEST_CASE(handles)

BEGIN_TEST_CASE(arrays)
RUN_TEST(close_array_of_present_handles)
RUN_TEST(close_out_of_line_array_of_nonnullable_handles)
END_TEST_CASE(arrays)

BEGIN_TEST_CASE(vectors)
RUN_TEST(close_present_too_large_nullable_vector_of_handles)
END_TEST_CASE(vectors)

} // namespace
} // namespace fidl
