| // Copyright 2017 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 <stddef.h> |
| |
| #include <fbl/type_support.h> |
| |
| #include <fidl/coding.h> |
| |
| #include <unittest/unittest.h> |
| |
| #include "fidl_coded_types.h" |
| #include "fidl_structs.h" |
| |
| namespace fidl { |
| namespace { |
| |
| // Some notes: |
| // |
| // - All tests of out-of-line bounded allocation overruns need to have |
| // another big out-of-line allocation following it. This |
| // distinguishes "the buffer is too small" from "the bits on the |
| // wire asked for more than the type allowed". |
| |
| // TODO(kulakowski) Change the tests to check for more specific error |
| // values, once those are settled. |
| |
| constexpr zx_handle_t dummy_handle_0 = 23; |
| constexpr zx_handle_t dummy_handle_1 = 24; |
| constexpr zx_handle_t dummy_handle_2 = 25; |
| constexpr zx_handle_t dummy_handle_3 = 26; |
| constexpr zx_handle_t dummy_handle_4 = 27; |
| constexpr zx_handle_t dummy_handle_5 = 28; |
| constexpr zx_handle_t dummy_handle_6 = 29; |
| constexpr zx_handle_t dummy_handle_7 = 30; |
| constexpr zx_handle_t dummy_handle_8 = 31; |
| constexpr zx_handle_t dummy_handle_9 = 32; |
| constexpr zx_handle_t dummy_handle_10 = 33; |
| constexpr zx_handle_t dummy_handle_11 = 34; |
| constexpr zx_handle_t dummy_handle_12 = 35; |
| constexpr zx_handle_t dummy_handle_13 = 36; |
| constexpr zx_handle_t dummy_handle_14 = 37; |
| constexpr zx_handle_t dummy_handle_15 = 38; |
| constexpr zx_handle_t dummy_handle_16 = 39; |
| constexpr zx_handle_t dummy_handle_17 = 40; |
| constexpr zx_handle_t dummy_handle_18 = 41; |
| constexpr zx_handle_t dummy_handle_19 = 42; |
| constexpr zx_handle_t dummy_handle_20 = 43; |
| constexpr zx_handle_t dummy_handle_21 = 44; |
| constexpr zx_handle_t dummy_handle_22 = 45; |
| constexpr zx_handle_t dummy_handle_23 = 46; |
| constexpr zx_handle_t dummy_handle_24 = 47; |
| constexpr zx_handle_t dummy_handle_25 = 48; |
| constexpr zx_handle_t dummy_handle_26 = 49; |
| constexpr zx_handle_t dummy_handle_27 = 50; |
| constexpr zx_handle_t dummy_handle_28 = 51; |
| constexpr zx_handle_t dummy_handle_29 = 52; |
| |
| // 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 encode_null_encode_parameters() { |
| BEGIN_TEST; |
| |
| zx_handle_t handles[1] = {}; |
| |
| // Null message type. |
| { |
| nonnullable_handle_message_layout message; |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(nullptr, &message, sizeof(nonnullable_handle_message_layout), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| } |
| |
| // Null message. |
| { |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nonnullable_handle_message_type, nullptr, |
| sizeof(nonnullable_handle_message_layout), handles, |
| ArrayCount(handles), &actual_handles, &error); |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| } |
| |
| // Null handles, for a message that has a handle. |
| { |
| nonnullable_handle_message_layout message; |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nonnullable_handle_message_type, &message, |
| sizeof(nonnullable_handle_message_layout), nullptr, 0, |
| &actual_handles, &error); |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| } |
| |
| // Null handles but positive handle count. |
| { |
| nonnullable_handle_message_layout message; |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nonnullable_handle_message_type, &message, |
| sizeof(nonnullable_handle_message_layout), nullptr, 1, |
| &actual_handles, &error); |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| } |
| |
| // A null actual handle count pointer. |
| { |
| nonnullable_handle_message_layout message; |
| const char* error = nullptr; |
| auto status = fidl_encode(&nonnullable_handle_message_type, &message, |
| sizeof(nonnullable_handle_message_layout), handles, |
| ArrayCount(handles), nullptr, &error); |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| } |
| |
| // A null error string pointer is ok, though. |
| { |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(nullptr, nullptr, 0u, nullptr, 0u, &actual_handles, nullptr); |
| EXPECT_NE(status, ZX_OK); |
| } |
| |
| // A null error is also ok in success cases. |
| { |
| nonnullable_handle_message_layout message = {}; |
| message.inline_struct.handle = dummy_handle_0; |
| |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nonnullable_handle_message_type, &message, |
| sizeof(nonnullable_handle_message_layout), handles, |
| ArrayCount(handles), &actual_handles, nullptr); |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_EQ(actual_handles, 1u); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(message.inline_struct.handle, FIDL_HANDLE_PRESENT); |
| } |
| |
| END_TEST; |
| } |
| |
| bool encode_single_present_handle() { |
| BEGIN_TEST; |
| |
| nonnullable_handle_message_layout message = {}; |
| message.inline_struct.handle = dummy_handle_0; |
| |
| zx_handle_t handles[1] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nonnullable_handle_message_type, &message, sizeof(message), handles, |
| ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 1u); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(message.inline_struct.handle, FIDL_HANDLE_PRESENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_multiple_present_handles() { |
| BEGIN_TEST; |
| |
| multiple_nonnullable_handles_message_layout message = {}; |
| message.inline_struct.handle_0 = dummy_handle_0; |
| message.inline_struct.handle_1 = dummy_handle_1; |
| message.inline_struct.handle_2 = dummy_handle_2; |
| |
| zx_handle_t handles[3] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&multiple_nonnullable_handles_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 3u); |
| EXPECT_EQ(message.inline_struct.data_0, 0u); |
| EXPECT_EQ(message.inline_struct.handle_0, FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.data_1, 0u); |
| EXPECT_EQ(message.inline_struct.handle_1, FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handle_2, FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.data_2, 0u); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| |
| END_TEST; |
| } |
| |
| bool encode_single_absent_handle() { |
| BEGIN_TEST; |
| |
| nullable_handle_message_layout message = {}; |
| message.inline_struct.handle = ZX_HANDLE_INVALID; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nullable_handle_message_type, &message, sizeof(message), nullptr, 0, |
| &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| EXPECT_EQ(message.inline_struct.handle, FIDL_HANDLE_ABSENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_multiple_absent_handles() { |
| BEGIN_TEST; |
| |
| multiple_nullable_handles_message_layout message = {}; |
| message.inline_struct.handle_0 = ZX_HANDLE_INVALID; |
| message.inline_struct.handle_1 = ZX_HANDLE_INVALID; |
| message.inline_struct.handle_2 = ZX_HANDLE_INVALID; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&multiple_nullable_handles_message_type, &message, sizeof(message), |
| nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| EXPECT_EQ(message.inline_struct.data_0, 0u); |
| EXPECT_EQ(message.inline_struct.handle_0, FIDL_HANDLE_ABSENT); |
| EXPECT_EQ(message.inline_struct.data_1, 0u); |
| EXPECT_EQ(message.inline_struct.handle_1, FIDL_HANDLE_ABSENT); |
| EXPECT_EQ(message.inline_struct.handle_2, FIDL_HANDLE_ABSENT); |
| EXPECT_EQ(message.inline_struct.data_2, 0u); |
| |
| END_TEST; |
| } |
| |
| bool encode_array_of_present_handles() { |
| BEGIN_TEST; |
| |
| array_of_nonnullable_handles_message_layout message = {}; |
| message.inline_struct.handles[0] = dummy_handle_0; |
| message.inline_struct.handles[1] = dummy_handle_1; |
| message.inline_struct.handles[2] = dummy_handle_2; |
| message.inline_struct.handles[3] = dummy_handle_3; |
| |
| zx_handle_t handles[4] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&array_of_nonnullable_handles_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 4u); |
| EXPECT_EQ(message.inline_struct.handles[0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[2], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[3], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| |
| END_TEST; |
| } |
| |
| bool encode_array_of_nullable_handles() { |
| BEGIN_TEST; |
| |
| array_of_nullable_handles_message_layout message = {}; |
| message.inline_struct.handles[0] = dummy_handle_0; |
| message.inline_struct.handles[1] = ZX_HANDLE_INVALID; |
| message.inline_struct.handles[2] = dummy_handle_1; |
| message.inline_struct.handles[3] = ZX_HANDLE_INVALID; |
| message.inline_struct.handles[4] = dummy_handle_2; |
| |
| zx_handle_t handles[3] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&array_of_nullable_handles_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 3u); |
| EXPECT_EQ(message.inline_struct.handles[0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[1], FIDL_HANDLE_ABSENT); |
| EXPECT_EQ(message.inline_struct.handles[2], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[3], FIDL_HANDLE_ABSENT); |
| EXPECT_EQ(message.inline_struct.handles[4], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| |
| END_TEST; |
| } |
| |
| bool encode_array_of_nullable_handles_with_insufficient_handles_error() { |
| BEGIN_TEST; |
| |
| array_of_nullable_handles_message_layout message = {}; |
| message.inline_struct.handles[0] = dummy_handle_0; |
| message.inline_struct.handles[1] = ZX_HANDLE_INVALID; |
| message.inline_struct.handles[2] = dummy_handle_1; |
| message.inline_struct.handles[3] = ZX_HANDLE_INVALID; |
| message.inline_struct.handles[4] = dummy_handle_2; |
| |
| zx_handle_t handles[2] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&array_of_nullable_handles_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| |
| END_TEST; |
| } |
| |
| bool encode_array_of_array_of_present_handles() { |
| BEGIN_TEST; |
| |
| array_of_array_of_nonnullable_handles_message_layout message = {}; |
| message.inline_struct.handles[0][0] = dummy_handle_0; |
| message.inline_struct.handles[0][1] = dummy_handle_1; |
| message.inline_struct.handles[0][2] = dummy_handle_2; |
| message.inline_struct.handles[0][3] = dummy_handle_3; |
| message.inline_struct.handles[1][0] = dummy_handle_4; |
| message.inline_struct.handles[1][1] = dummy_handle_5; |
| message.inline_struct.handles[1][2] = dummy_handle_6; |
| message.inline_struct.handles[1][3] = dummy_handle_7; |
| message.inline_struct.handles[2][0] = dummy_handle_8; |
| message.inline_struct.handles[2][1] = dummy_handle_9; |
| message.inline_struct.handles[2][2] = dummy_handle_10; |
| message.inline_struct.handles[2][3] = dummy_handle_11; |
| |
| zx_handle_t handles[12] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&array_of_array_of_nonnullable_handles_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 12u); |
| EXPECT_EQ(message.inline_struct.handles[0][0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[0][1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[0][2], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[0][3], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[1][0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[1][1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[1][2], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[1][3], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[2][0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[2][1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[2][2], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.handles[2][3], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| EXPECT_EQ(handles[4], dummy_handle_4); |
| EXPECT_EQ(handles[5], dummy_handle_5); |
| EXPECT_EQ(handles[6], dummy_handle_6); |
| EXPECT_EQ(handles[7], dummy_handle_7); |
| EXPECT_EQ(handles[8], dummy_handle_8); |
| EXPECT_EQ(handles[9], dummy_handle_9); |
| EXPECT_EQ(handles[10], dummy_handle_10); |
| EXPECT_EQ(handles[11], dummy_handle_11); |
| |
| END_TEST; |
| } |
| |
| bool encode_out_of_line_array_of_nonnullable_handles() { |
| BEGIN_TEST; |
| |
| out_of_line_array_of_nonnullable_handles_message_layout message = {}; |
| message.inline_struct.maybe_array = &message.data; |
| message.data.handles[0] = dummy_handle_0; |
| message.data.handles[1] = dummy_handle_1; |
| message.data.handles[2] = dummy_handle_2; |
| message.data.handles[3] = dummy_handle_3; |
| |
| zx_handle_t handles[4] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&out_of_line_array_of_nonnullable_handles_message_type, &message, |
| sizeof(message), handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 4u); |
| |
| auto array_ptr = reinterpret_cast<uint64_t>(message.inline_struct.maybe_array); |
| EXPECT_EQ(array_ptr, FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(message.data.handles[0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.data.handles[1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.data.handles[2], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.data.handles[3], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nonnullable_string() { |
| BEGIN_TEST; |
| |
| unbounded_nonnullable_string_message_layout message = {}; |
| message.inline_struct.string = fidl_string_t{6, &message.data[0]}; |
| memcpy(message.data, "hello!", 6); |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&unbounded_nonnullable_string_message_type, &message, sizeof(message), |
| nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.string.data), FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(message.inline_struct.string.size, 6); |
| EXPECT_EQ(message.data[0], 'h'); |
| EXPECT_EQ(message.data[1], 'e'); |
| EXPECT_EQ(message.data[2], 'l'); |
| EXPECT_EQ(message.data[3], 'l'); |
| EXPECT_EQ(message.data[4], 'o'); |
| EXPECT_EQ(message.data[5], '!'); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nullable_string() { |
| BEGIN_TEST; |
| |
| unbounded_nullable_string_message_layout message = {}; |
| message.inline_struct.string = fidl_string_t{6, &message.data[0]}; |
| memcpy(message.data, "hello!", 6); |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&unbounded_nullable_string_message_type, &message, sizeof(message), |
| nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| EXPECT_EQ(message.inline_struct.string.size, 6); |
| EXPECT_EQ(message.data[0], 'h'); |
| EXPECT_EQ(message.data[1], 'e'); |
| EXPECT_EQ(message.data[2], 'l'); |
| EXPECT_EQ(message.data[3], 'l'); |
| EXPECT_EQ(message.data[4], 'o'); |
| EXPECT_EQ(message.data[5], '!'); |
| |
| END_TEST; |
| } |
| |
| bool encode_multiple_present_nullable_string() { |
| BEGIN_TEST; |
| |
| // Among other things, this test ensures we handle out-of-line |
| // alignment to FIDL_ALIGNMENT (i.e., 8) bytes correctly. |
| multiple_nullable_strings_message_layout message; |
| message.inline_struct.string = fidl_string_t{6, &message.data[0]}; |
| message.inline_struct.string2 = fidl_string_t{8, &message.data2[0]}; |
| memcpy(message.data, "hello ", 6); |
| memcpy(message.data2, "world!!!", 8); |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&multiple_nullable_strings_message_type, &message, sizeof(message), |
| nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| EXPECT_EQ(message.inline_struct.string.size, 6); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.string.data), FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(message.data[0], 'h'); |
| EXPECT_EQ(message.data[1], 'e'); |
| EXPECT_EQ(message.data[2], 'l'); |
| EXPECT_EQ(message.data[3], 'l'); |
| EXPECT_EQ(message.data[4], 'o'); |
| EXPECT_EQ(message.data[5], ' '); |
| EXPECT_EQ(message.inline_struct.string2.size, 8); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.string2.data), FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(message.data2[0], 'w'); |
| EXPECT_EQ(message.data2[1], 'o'); |
| EXPECT_EQ(message.data2[2], 'r'); |
| EXPECT_EQ(message.data2[3], 'l'); |
| EXPECT_EQ(message.data2[4], 'd'); |
| EXPECT_EQ(message.data2[5], '!'); |
| EXPECT_EQ(message.data2[6], '!'); |
| EXPECT_EQ(message.data2[7], '!'); |
| |
| END_TEST; |
| } |
| |
| bool encode_absent_nonnullable_string_error() { |
| BEGIN_TEST; |
| |
| unbounded_nonnullable_string_message_layout message = {}; |
| message.inline_struct.string = fidl_string_t{0u, nullptr}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&unbounded_nonnullable_string_message_type, &message, sizeof(message), |
| nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error, error); |
| |
| END_TEST; |
| } |
| |
| bool encode_absent_nullable_string() { |
| BEGIN_TEST; |
| |
| unbounded_nullable_string_message_layout message = {}; |
| message.inline_struct.string = fidl_string_t{0u, nullptr}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&unbounded_nullable_string_message_type, &message, |
| sizeof(message.inline_struct), nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.string.data), FIDL_ALLOC_ABSENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nonnullable_bounded_string() { |
| BEGIN_TEST; |
| |
| bounded_32_nonnullable_string_message_layout message = {}; |
| message.inline_struct.string = fidl_string_t{6, &message.data[0]}; |
| memcpy(message.data, "hello!", 6); |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&bounded_32_nonnullable_string_message_type, &message, |
| sizeof(message), nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| EXPECT_EQ(message.inline_struct.string.size, 6); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.string.data), FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(message.data[0], 'h'); |
| EXPECT_EQ(message.data[1], 'e'); |
| EXPECT_EQ(message.data[2], 'l'); |
| EXPECT_EQ(message.data[3], 'l'); |
| EXPECT_EQ(message.data[4], 'o'); |
| EXPECT_EQ(message.data[5], '!'); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nullable_bounded_string() { |
| BEGIN_TEST; |
| |
| bounded_32_nullable_string_message_layout message = {}; |
| message.inline_struct.string = fidl_string_t{6, &message.data[0]}; |
| memcpy(message.data, "hello!", 6); |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&bounded_32_nullable_string_message_type, &message, sizeof(message), |
| nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| EXPECT_EQ(message.inline_struct.string.size, 6); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.string.data), FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(message.data[0], 'h'); |
| EXPECT_EQ(message.data[1], 'e'); |
| EXPECT_EQ(message.data[2], 'l'); |
| EXPECT_EQ(message.data[3], 'l'); |
| EXPECT_EQ(message.data[4], 'o'); |
| EXPECT_EQ(message.data[5], '!'); |
| |
| END_TEST; |
| } |
| |
| bool encode_absent_nonnullable_bounded_string_error() { |
| BEGIN_TEST; |
| |
| bounded_32_nonnullable_string_message_layout message = {}; |
| message.inline_struct.string = fidl_string_t{6, nullptr}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&bounded_32_nonnullable_string_message_type, &message, |
| sizeof(message), nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error, error); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.string.data), FIDL_ALLOC_ABSENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_absent_nullable_bounded_string() { |
| BEGIN_TEST; |
| |
| bounded_32_nullable_string_message_layout message = {}; |
| message.inline_struct.string = fidl_string_t{6, nullptr}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&bounded_32_nullable_string_message_type, &message, |
| sizeof(message.inline_struct), nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.string.data), FIDL_ALLOC_ABSENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nonnullable_bounded_string_short_error() { |
| BEGIN_TEST; |
| |
| multiple_short_nonnullable_strings_message_layout message = {}; |
| message.inline_struct.string = fidl_string_t{6, &message.data[0]}; |
| message.inline_struct.string2 = fidl_string_t{6, &message.data2[0]}; |
| memcpy(message.data, "hello!", 6); |
| memcpy(message.data2, "hello!", 6); |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&multiple_short_nonnullable_strings_message_type, &message, |
| sizeof(message), nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nullable_bounded_string_short_error() { |
| BEGIN_TEST; |
| |
| multiple_short_nullable_strings_message_layout message = {}; |
| message.inline_struct.string = fidl_string_t{6, &message.data[0]}; |
| message.inline_struct.string2 = fidl_string_t{6, &message.data2[0]}; |
| memcpy(message.data, "hello!", 6); |
| memcpy(message.data2, "hello!", 6); |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&multiple_short_nullable_strings_message_type, &message, |
| sizeof(message), nullptr, 0, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nonnullable_vector_of_handles() { |
| BEGIN_TEST; |
| |
| unbounded_nonnullable_vector_of_handles_message_layout message = {}; |
| message.inline_struct.vector = fidl_vector_t{4, &message.handles[0]}; |
| message.handles[0] = dummy_handle_0; |
| message.handles[1] = dummy_handle_1; |
| message.handles[2] = dummy_handle_2; |
| message.handles[3] = dummy_handle_3; |
| |
| zx_handle_t handles[4] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&unbounded_nonnullable_vector_of_handles_message_type, &message, |
| sizeof(message), handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 4u); |
| |
| auto message_handles = reinterpret_cast<uint64_t>(message.inline_struct.vector.data); |
| EXPECT_EQ(message_handles, FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| EXPECT_EQ(message.handles[0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[2], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[3], FIDL_HANDLE_PRESENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nullable_vector_of_handles() { |
| BEGIN_TEST; |
| |
| unbounded_nullable_vector_of_handles_message_layout message = {}; |
| message.inline_struct.vector = fidl_vector_t{4, &message.handles[0]}; |
| message.handles[0] = dummy_handle_0; |
| message.handles[1] = dummy_handle_1; |
| message.handles[2] = dummy_handle_2; |
| message.handles[3] = dummy_handle_3; |
| |
| zx_handle_t handles[4] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&unbounded_nullable_vector_of_handles_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 4u); |
| |
| auto message_handles = reinterpret_cast<uint64_t>(message.inline_struct.vector.data); |
| EXPECT_EQ(message_handles, FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| EXPECT_EQ(message.handles[0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[2], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[3], FIDL_HANDLE_PRESENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_absent_nonnullable_vector_of_handles_error() { |
| BEGIN_TEST; |
| |
| unbounded_nonnullable_vector_of_handles_message_layout message = {}; |
| message.inline_struct.vector = fidl_vector_t{4, nullptr}; |
| |
| zx_handle_t handles[4] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&unbounded_nonnullable_vector_of_handles_message_type, &message, |
| sizeof(message), handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error, error); |
| |
| END_TEST; |
| } |
| |
| bool encode_absent_nullable_vector_of_handles() { |
| BEGIN_TEST; |
| |
| unbounded_nullable_vector_of_handles_message_layout message = {}; |
| message.inline_struct.vector = fidl_vector_t{4, nullptr}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&unbounded_nullable_vector_of_handles_message_type, &message, |
| sizeof(message.inline_struct), nullptr, 0u, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| |
| auto message_handles = reinterpret_cast<uint64_t>(message.inline_struct.vector.data); |
| EXPECT_EQ(message_handles, FIDL_ALLOC_ABSENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nonnullable_bounded_vector_of_handles() { |
| BEGIN_TEST; |
| |
| bounded_32_nonnullable_vector_of_handles_message_layout message = {}; |
| message.inline_struct.vector = fidl_vector_t{4, &message.handles[0]}; |
| message.handles[0] = dummy_handle_0; |
| message.handles[1] = dummy_handle_1; |
| message.handles[2] = dummy_handle_2; |
| message.handles[3] = dummy_handle_3; |
| |
| zx_handle_t handles[4] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&bounded_32_nonnullable_vector_of_handles_message_type, &message, |
| sizeof(message), handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 4u); |
| |
| auto message_handles = reinterpret_cast<uint64_t>(message.inline_struct.vector.data); |
| EXPECT_EQ(message_handles, FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| EXPECT_EQ(message.handles[0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[2], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[3], FIDL_HANDLE_PRESENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nullable_bounded_vector_of_handles() { |
| BEGIN_TEST; |
| |
| bounded_32_nullable_vector_of_handles_message_layout message = {}; |
| message.inline_struct.vector = fidl_vector_t{4, &message.handles[0]}; |
| message.handles[0] = dummy_handle_0; |
| message.handles[1] = dummy_handle_1; |
| message.handles[2] = dummy_handle_2; |
| message.handles[3] = dummy_handle_3; |
| |
| zx_handle_t handles[4] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&bounded_32_nullable_vector_of_handles_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 4u); |
| |
| auto message_handles = reinterpret_cast<uint64_t>(message.inline_struct.vector.data); |
| EXPECT_EQ(message_handles, FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| EXPECT_EQ(message.handles[0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[2], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.handles[3], FIDL_HANDLE_PRESENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_absent_nonnullable_bounded_vector_of_handles() { |
| BEGIN_TEST; |
| |
| bounded_32_nonnullable_vector_of_handles_message_layout message = {}; |
| message.inline_struct.vector = fidl_vector_t{4, nullptr}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&bounded_32_nonnullable_vector_of_handles_message_type, &message, |
| sizeof(message), nullptr, 0u, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| |
| END_TEST; |
| } |
| |
| bool encode_absent_nullable_bounded_vector_of_handles() { |
| BEGIN_TEST; |
| |
| bounded_32_nullable_vector_of_handles_message_layout message = {}; |
| message.inline_struct.vector = fidl_vector_t{4, nullptr}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&bounded_32_nullable_vector_of_handles_message_type, &message, |
| sizeof(message.inline_struct), nullptr, 0u, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| |
| auto message_handles = reinterpret_cast<uint64_t>(message.inline_struct.vector.data); |
| EXPECT_EQ(message_handles, FIDL_ALLOC_ABSENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nonnullable_bounded_vector_of_handles_short_error() { |
| BEGIN_TEST; |
| |
| multiple_nonnullable_vectors_of_handles_message_layout message = {}; |
| message.inline_struct.vector = fidl_vector_t{4, &message.handles[0]}; |
| message.inline_struct.vector2 = fidl_vector_t{4, &message.handles2[0]}; |
| message.handles[0] = dummy_handle_0; |
| message.handles[1] = dummy_handle_1; |
| message.handles[2] = dummy_handle_2; |
| message.handles[3] = dummy_handle_3; |
| message.handles2[0] = dummy_handle_4; |
| message.handles2[1] = dummy_handle_5; |
| message.handles2[2] = dummy_handle_6; |
| message.handles2[3] = dummy_handle_7; |
| |
| zx_handle_t handles[8] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&multiple_nonnullable_vectors_of_handles_message_type, &message, |
| sizeof(message), handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| |
| END_TEST; |
| } |
| |
| bool encode_present_nullable_bounded_vector_of_handles_short_error() { |
| BEGIN_TEST; |
| |
| multiple_nullable_vectors_of_handles_message_layout message = {}; |
| message.inline_struct.vector = fidl_vector_t{4, &message.handles[0]}; |
| message.inline_struct.vector2 = fidl_vector_t{4, &message.handles2[0]}; |
| message.handles[0] = dummy_handle_0; |
| message.handles[1] = dummy_handle_1; |
| message.handles[2] = dummy_handle_2; |
| message.handles[3] = dummy_handle_3; |
| message.handles2[0] = dummy_handle_4; |
| message.handles2[1] = dummy_handle_5; |
| message.handles2[2] = dummy_handle_6; |
| message.handles2[3] = dummy_handle_7; |
| |
| zx_handle_t handles[8] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&multiple_nullable_vectors_of_handles_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| |
| END_TEST; |
| } |
| |
| bool encode_bad_tagged_union_error() { |
| BEGIN_TEST; |
| |
| nonnullable_handle_union_message_layout message = {}; |
| message.inline_struct.data.tag = 52u; |
| message.inline_struct.data.handle = dummy_handle_0; |
| |
| zx_handle_t handles[1] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nonnullable_handle_union_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| |
| END_TEST; |
| } |
| |
| bool encode_single_armed_present_nonnullable_union() { |
| BEGIN_TEST; |
| |
| nonnullable_handle_union_message_layout message = {}; |
| message.inline_struct.data.tag = nonnullable_handle_union_kHandle; |
| message.inline_struct.data.handle = dummy_handle_0; |
| |
| zx_handle_t handles[1] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nonnullable_handle_union_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 1u); |
| EXPECT_EQ(message.inline_struct.data.tag, nonnullable_handle_union_kHandle); |
| EXPECT_EQ(message.inline_struct.data.handle, FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| |
| END_TEST; |
| } |
| |
| bool encode_many_armed_present_nonnullable_union() { |
| BEGIN_TEST; |
| |
| array_of_nonnullable_handles_union_message_layout message = {}; |
| message.inline_struct.data.tag = array_of_nonnullable_handles_union_kArrayOfArrayOfHandles; |
| message.inline_struct.data.array_of_array_of_handles[0][0] = dummy_handle_0; |
| message.inline_struct.data.array_of_array_of_handles[0][1] = dummy_handle_1; |
| message.inline_struct.data.array_of_array_of_handles[1][0] = dummy_handle_2; |
| message.inline_struct.data.array_of_array_of_handles[1][1] = dummy_handle_3; |
| |
| zx_handle_t handles[4] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&array_of_nonnullable_handles_union_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 4u); |
| EXPECT_EQ(message.inline_struct.data.tag, |
| array_of_nonnullable_handles_union_kArrayOfArrayOfHandles); |
| EXPECT_EQ(message.inline_struct.data.array_of_array_of_handles[0][0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.data.array_of_array_of_handles[0][1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.data.array_of_array_of_handles[1][0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.data.array_of_array_of_handles[1][1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| |
| END_TEST; |
| } |
| |
| bool encode_single_armed_present_nullable_union() { |
| BEGIN_TEST; |
| |
| nonnullable_handle_union_ptr_message_layout message = {}; |
| message.inline_struct.data = &message.data; |
| message.data.tag = nonnullable_handle_union_kHandle; |
| message.data.handle = dummy_handle_0; |
| |
| zx_handle_t handles[1] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nonnullable_handle_union_ptr_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 1u); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.data), FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(message.data.tag, nonnullable_handle_union_kHandle); |
| EXPECT_EQ(message.data.handle, FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| |
| END_TEST; |
| } |
| |
| bool encode_many_armed_present_nullable_union() { |
| BEGIN_TEST; |
| |
| array_of_nonnullable_handles_union_ptr_message_layout message = {}; |
| message.inline_struct.data = &message.data; |
| message.data.tag = array_of_nonnullable_handles_union_kArrayOfArrayOfHandles; |
| message.data.array_of_array_of_handles[0][0] = dummy_handle_0; |
| message.data.array_of_array_of_handles[0][1] = dummy_handle_1; |
| message.data.array_of_array_of_handles[1][0] = dummy_handle_2; |
| message.data.array_of_array_of_handles[1][1] = dummy_handle_3; |
| |
| zx_handle_t handles[4] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = |
| fidl_encode(&array_of_nonnullable_handles_union_ptr_message_type, &message, sizeof(message), |
| handles, ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 4u); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.data), FIDL_ALLOC_PRESENT); |
| EXPECT_EQ(message.data.tag, array_of_nonnullable_handles_union_kArrayOfArrayOfHandles); |
| EXPECT_EQ(message.data.array_of_array_of_handles[0][0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.data.array_of_array_of_handles[0][1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.data.array_of_array_of_handles[1][0], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.data.array_of_array_of_handles[1][1], FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| |
| END_TEST; |
| } |
| |
| bool encode_single_armed_absent_nullable_union() { |
| BEGIN_TEST; |
| |
| nonnullable_handle_union_ptr_message_layout message = {}; |
| message.inline_struct.data = nullptr; |
| |
| zx_handle_t handles[1] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nonnullable_handle_union_ptr_message_type, &message, |
| sizeof(message.inline_struct), handles, ArrayCount(handles), |
| &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.data), FIDL_ALLOC_ABSENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_many_armed_absent_nullable_union() { |
| BEGIN_TEST; |
| |
| array_of_nonnullable_handles_union_ptr_message_layout message = {}; |
| message.inline_struct.data = nullptr; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&array_of_nonnullable_handles_union_ptr_message_type, &message, |
| sizeof(message.inline_struct), nullptr, 0u, &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| EXPECT_EQ(actual_handles, 0u); |
| EXPECT_EQ(reinterpret_cast<uint64_t>(message.inline_struct.data), FIDL_ALLOC_ABSENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_nested_nonnullable_structs() { |
| BEGIN_TEST; |
| |
| // Note the traversal order! l1 -> l3 -> l2 -> l0 |
| nested_structs_message_layout message = {}; |
| message.inline_struct.l0.l1.handle_1 = dummy_handle_0; |
| message.inline_struct.l0.l1.l2.l3.handle_3 = dummy_handle_1; |
| message.inline_struct.l0.l1.l2.handle_2 = dummy_handle_2; |
| message.inline_struct.l0.handle_0 = dummy_handle_3; |
| |
| zx_handle_t handles[4] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nested_structs_message_type, &message, sizeof(message), handles, |
| ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| |
| EXPECT_EQ(message.inline_struct.l0.l1.handle_1, FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.l0.l1.l2.l3.handle_3, FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.l0.l1.l2.handle_2, FIDL_HANDLE_PRESENT); |
| EXPECT_EQ(message.inline_struct.l0.handle_0, FIDL_HANDLE_PRESENT); |
| |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| |
| END_TEST; |
| } |
| |
| bool encode_nested_nullable_structs() { |
| BEGIN_TEST; |
| |
| nested_struct_ptrs_message_layout message = {}; |
| message.inline_struct.l0_inline.l1_inline.l2_present = &message.in_in_out_2; |
| message.inline_struct.l0_inline.l1_inline.l2_present->l3_present = &message.in_in_out_out_3; |
| message.inline_struct.l0_inline.l1_inline.l2_inline.l3_present = &message.in_in_in_out_3; |
| message.inline_struct.l0_inline.l1_present = &message.in_out_1; |
| message.inline_struct.l0_inline.l1_present->l2_present = &message.in_out_out_2; |
| message.inline_struct.l0_inline.l1_present->l2_present->l3_present = &message.in_out_out_out_3; |
| message.inline_struct.l0_inline.l1_present->l2_inline.l3_present = &message.in_out_in_out_3; |
| message.inline_struct.l0_present = &message.out_0; |
| message.inline_struct.l0_present->l1_inline.l2_present = &message.out_in_out_2; |
| message.inline_struct.l0_present->l1_inline.l2_present->l3_present = &message.out_in_out_out_3; |
| message.inline_struct.l0_present->l1_inline.l2_inline.l3_present = &message.out_in_in_out_3; |
| message.inline_struct.l0_present->l1_present = &message.out_out_1; |
| message.inline_struct.l0_present->l1_present->l2_present = &message.out_out_out_2; |
| message.inline_struct.l0_present->l1_present->l2_present->l3_present = |
| &message.out_out_out_out_3; |
| message.inline_struct.l0_present->l1_present->l2_inline.l3_present = &message.out_out_in_out_3; |
| |
| // 0 inline |
| // 1 inline |
| // handle |
| message.inline_struct.l0_inline.l1_inline.handle_1 = dummy_handle_0; |
| // 2 out of line |
| // 3 out of line |
| message.in_in_out_out_3.handle_3 = dummy_handle_1; |
| // 3 inline |
| message.in_in_out_2.l3_inline.handle_3 = dummy_handle_2; |
| // handle |
| message.in_in_out_2.handle_2 = dummy_handle_3; |
| // 2 inline |
| // 3 out of line |
| message.in_in_in_out_3.handle_3 = dummy_handle_4; |
| // 3 inline |
| message.inline_struct.l0_inline.l1_inline.l2_inline.l3_inline.handle_3 = dummy_handle_5; |
| // handle |
| message.inline_struct.l0_inline.l1_inline.l2_inline.handle_2 = dummy_handle_6; |
| // handle |
| message.inline_struct.l0_inline.handle_0 = dummy_handle_7; |
| // 1 out of line |
| // handle |
| message.in_out_1.handle_1 = dummy_handle_8; |
| // 2 out of line |
| // 3 out of line |
| message.in_out_out_out_3.handle_3 = dummy_handle_9; |
| // 3 inline |
| message.in_out_out_2.l3_inline.handle_3 = dummy_handle_10; |
| // handle |
| message.in_out_out_2.handle_2 = dummy_handle_11; |
| // 2 inline |
| // 3 out of line |
| message.in_out_in_out_3.handle_3 = dummy_handle_12; |
| // 3 inline |
| message.in_out_1.l2_inline.l3_inline.handle_3 = dummy_handle_13; |
| // handle |
| message.in_out_1.l2_inline.handle_2 = dummy_handle_14; |
| // 0 out of line |
| // 1 inline |
| // handle |
| message.out_0.l1_inline.handle_1 = dummy_handle_15; |
| // 2 out of line |
| // 3 out of line |
| message.out_in_out_out_3.handle_3 = dummy_handle_16; |
| // 3 inline |
| message.out_in_out_2.l3_inline.handle_3 = dummy_handle_17; |
| // handle |
| message.out_in_out_2.handle_2 = dummy_handle_18; |
| // 2 inline |
| // 3 out of line |
| message.out_in_in_out_3.handle_3 = dummy_handle_19; |
| // 3 inline |
| message.out_0.l1_inline.l2_inline.l3_inline.handle_3 = dummy_handle_20; |
| // handle |
| message.out_0.l1_inline.l2_inline.handle_2 = dummy_handle_21; |
| // handle |
| message.out_0.handle_0 = dummy_handle_22; |
| // 1 out of line |
| // handle |
| message.out_out_1.handle_1 = dummy_handle_23; |
| // 2 out of line |
| // 3 out of line |
| message.out_out_out_out_3.handle_3 = dummy_handle_24; |
| // 3 inline |
| message.out_out_out_2.l3_inline.handle_3 = dummy_handle_25; |
| // handle |
| message.out_out_out_2.handle_2 = dummy_handle_26; |
| // 2 inline |
| // 3 out of line |
| message.out_out_in_out_3.handle_3 = dummy_handle_27; |
| // 3 inline |
| message.out_out_1.l2_inline.l3_inline.handle_3 = dummy_handle_28; |
| // handle |
| message.out_out_1.l2_inline.handle_2 = dummy_handle_29; |
| |
| zx_handle_t handles[30] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&nested_struct_ptrs_message_type, &message, sizeof(message), handles, |
| ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_OK); |
| EXPECT_NULL(error, error); |
| |
| EXPECT_EQ(handles[0], dummy_handle_0); |
| EXPECT_EQ(handles[1], dummy_handle_1); |
| EXPECT_EQ(handles[2], dummy_handle_2); |
| EXPECT_EQ(handles[3], dummy_handle_3); |
| EXPECT_EQ(handles[4], dummy_handle_4); |
| EXPECT_EQ(handles[5], dummy_handle_5); |
| EXPECT_EQ(handles[6], dummy_handle_6); |
| EXPECT_EQ(handles[7], dummy_handle_7); |
| EXPECT_EQ(handles[8], dummy_handle_8); |
| EXPECT_EQ(handles[9], dummy_handle_9); |
| EXPECT_EQ(handles[10], dummy_handle_10); |
| EXPECT_EQ(handles[11], dummy_handle_11); |
| EXPECT_EQ(handles[12], dummy_handle_12); |
| EXPECT_EQ(handles[13], dummy_handle_13); |
| EXPECT_EQ(handles[14], dummy_handle_14); |
| EXPECT_EQ(handles[15], dummy_handle_15); |
| EXPECT_EQ(handles[16], dummy_handle_16); |
| EXPECT_EQ(handles[17], dummy_handle_17); |
| EXPECT_EQ(handles[18], dummy_handle_18); |
| EXPECT_EQ(handles[19], dummy_handle_19); |
| EXPECT_EQ(handles[20], dummy_handle_20); |
| EXPECT_EQ(handles[21], dummy_handle_21); |
| EXPECT_EQ(handles[22], dummy_handle_22); |
| EXPECT_EQ(handles[23], dummy_handle_23); |
| EXPECT_EQ(handles[24], dummy_handle_24); |
| EXPECT_EQ(handles[25], dummy_handle_25); |
| EXPECT_EQ(handles[26], dummy_handle_26); |
| EXPECT_EQ(handles[27], dummy_handle_27); |
| EXPECT_EQ(handles[28], dummy_handle_28); |
| EXPECT_EQ(handles[29], dummy_handle_29); |
| |
| // Finally, check that all absent members are FIDL_ALLOC_ABSENT. |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.inline_struct.l0_absent), FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.inline_struct.l0_inline.l1_absent), |
| FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.inline_struct.l0_inline.l1_inline.l2_absent), |
| FIDL_ALLOC_ABSENT); |
| EXPECT_EQ( |
| reinterpret_cast<uintptr_t>(message.inline_struct.l0_inline.l1_inline.l2_inline.l3_absent), |
| FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.in_in_out_2.l3_absent), FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.in_out_1.l2_absent), FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.in_out_1.l2_inline.l3_absent), FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.in_out_out_2.l3_absent), FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.out_0.l1_absent), FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.out_0.l1_inline.l2_absent), FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.out_0.l1_inline.l2_inline.l3_absent), |
| FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.out_in_out_2.l3_absent), FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.out_out_1.l2_absent), FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.out_out_1.l2_inline.l3_absent), |
| FIDL_ALLOC_ABSENT); |
| EXPECT_EQ(reinterpret_cast<uintptr_t>(message.out_out_out_2.l3_absent), FIDL_ALLOC_ABSENT); |
| |
| END_TEST; |
| } |
| |
| bool encode_nested_struct_recursion_too_deep_error() { |
| BEGIN_TEST; |
| |
| recursion_message_layout message = {}; |
| message.inline_struct.start.tag = maybe_recurse_union_kMore; |
| message.inline_struct.start.more = &message.depth_0; |
| message.depth_0.tag = maybe_recurse_union_kMore; |
| message.depth_0.more = &message.depth_1; |
| message.depth_1.tag = maybe_recurse_union_kMore; |
| message.depth_1.more = &message.depth_2; |
| message.depth_2.tag = maybe_recurse_union_kMore; |
| message.depth_2.more = &message.depth_3; |
| message.depth_3.tag = maybe_recurse_union_kMore; |
| message.depth_3.more = &message.depth_4; |
| message.depth_4.tag = maybe_recurse_union_kMore; |
| message.depth_4.more = &message.depth_5; |
| message.depth_5.tag = maybe_recurse_union_kMore; |
| message.depth_5.more = &message.depth_6; |
| message.depth_6.tag = maybe_recurse_union_kMore; |
| message.depth_6.more = &message.depth_7; |
| message.depth_7.tag = maybe_recurse_union_kMore; |
| message.depth_7.more = &message.depth_8; |
| message.depth_8.tag = maybe_recurse_union_kMore; |
| message.depth_8.more = &message.depth_9; |
| message.depth_9.tag = maybe_recurse_union_kMore; |
| message.depth_9.more = &message.depth_10; |
| message.depth_10.tag = maybe_recurse_union_kMore; |
| message.depth_10.more = &message.depth_11; |
| message.depth_11.tag = maybe_recurse_union_kMore; |
| message.depth_11.more = &message.depth_12; |
| message.depth_12.tag = maybe_recurse_union_kMore; |
| message.depth_12.more = &message.depth_13; |
| message.depth_13.tag = maybe_recurse_union_kMore; |
| message.depth_13.more = &message.depth_14; |
| message.depth_14.tag = maybe_recurse_union_kMore; |
| message.depth_14.more = &message.depth_15; |
| message.depth_15.tag = maybe_recurse_union_kMore; |
| message.depth_15.more = &message.depth_16; |
| message.depth_16.tag = maybe_recurse_union_kMore; |
| message.depth_16.more = &message.depth_17; |
| message.depth_17.tag = maybe_recurse_union_kMore; |
| message.depth_17.more = &message.depth_18; |
| message.depth_18.tag = maybe_recurse_union_kMore; |
| message.depth_18.more = &message.depth_19; |
| message.depth_19.tag = maybe_recurse_union_kMore; |
| message.depth_19.more = &message.depth_20; |
| message.depth_20.tag = maybe_recurse_union_kMore; |
| message.depth_20.more = &message.depth_21; |
| message.depth_21.tag = maybe_recurse_union_kMore; |
| message.depth_21.more = &message.depth_22; |
| message.depth_22.tag = maybe_recurse_union_kMore; |
| message.depth_22.more = &message.depth_23; |
| message.depth_23.tag = maybe_recurse_union_kMore; |
| message.depth_23.more = &message.depth_24; |
| message.depth_24.tag = maybe_recurse_union_kMore; |
| message.depth_24.more = &message.depth_25; |
| message.depth_25.tag = maybe_recurse_union_kMore; |
| message.depth_25.more = &message.depth_26; |
| message.depth_26.tag = maybe_recurse_union_kMore; |
| message.depth_26.more = &message.depth_27; |
| message.depth_27.tag = maybe_recurse_union_kMore; |
| message.depth_27.more = &message.depth_28; |
| message.depth_28.tag = maybe_recurse_union_kMore; |
| message.depth_28.more = &message.depth_29; |
| message.depth_29.tag = maybe_recurse_union_kMore; |
| message.depth_29.more = &message.depth_30; |
| message.depth_30.tag = maybe_recurse_union_kMore; |
| message.depth_30.more = &message.depth_31; |
| message.depth_31.tag = maybe_recurse_union_kMore; |
| message.depth_31.more = &message.depth_32; |
| message.depth_32.tag = maybe_recurse_union_kMore; |
| message.depth_32.more = &message.depth_33; |
| message.depth_33.tag = maybe_recurse_union_kMore; |
| message.depth_33.more = &message.depth_34; |
| message.depth_34.tag = maybe_recurse_union_kDone; |
| message.depth_34.done = &message.done; |
| message.done.handle = dummy_handle_0; |
| |
| zx_handle_t handles[1] = {}; |
| |
| const char* error = nullptr; |
| uint32_t actual_handles = 0u; |
| auto status = fidl_encode(&recursion_message_type, &message, sizeof(message), handles, |
| ArrayCount(handles), &actual_handles, &error); |
| |
| EXPECT_EQ(status, ZX_ERR_INVALID_ARGS); |
| EXPECT_NONNULL(error); |
| |
| END_TEST; |
| } |
| |
| BEGIN_TEST_CASE(null_parameters) |
| RUN_TEST(encode_null_encode_parameters) |
| END_TEST_CASE(null_parameters) |
| |
| BEGIN_TEST_CASE(handles) |
| RUN_TEST(encode_single_present_handle) |
| RUN_TEST(encode_multiple_present_handles) |
| RUN_TEST(encode_single_absent_handle) |
| RUN_TEST(encode_multiple_absent_handles) |
| END_TEST_CASE(handles) |
| |
| BEGIN_TEST_CASE(arrays) |
| RUN_TEST(encode_array_of_present_handles) |
| RUN_TEST(encode_array_of_nullable_handles) |
| RUN_TEST(encode_array_of_nullable_handles_with_insufficient_handles_error) |
| RUN_TEST(encode_array_of_array_of_present_handles) |
| RUN_TEST(encode_out_of_line_array_of_nonnullable_handles) |
| END_TEST_CASE(arrays) |
| |
| BEGIN_TEST_CASE(strings) |
| RUN_TEST(encode_present_nonnullable_string) |
| RUN_TEST(encode_multiple_present_nullable_string) |
| RUN_TEST(encode_present_nullable_string) |
| RUN_TEST(encode_absent_nonnullable_string_error) |
| RUN_TEST(encode_absent_nullable_string) |
| RUN_TEST(encode_present_nonnullable_bounded_string) |
| RUN_TEST(encode_present_nullable_bounded_string) |
| RUN_TEST(encode_absent_nonnullable_bounded_string_error) |
| RUN_TEST(encode_absent_nullable_bounded_string) |
| RUN_TEST(encode_present_nonnullable_bounded_string_short_error) |
| RUN_TEST(encode_present_nullable_bounded_string_short_error) |
| END_TEST_CASE(strings) |
| |
| BEGIN_TEST_CASE(vectors) |
| RUN_TEST(encode_present_nonnullable_vector_of_handles) |
| RUN_TEST(encode_present_nullable_vector_of_handles) |
| RUN_TEST(encode_absent_nonnullable_vector_of_handles_error) |
| RUN_TEST(encode_absent_nullable_vector_of_handles) |
| RUN_TEST(encode_present_nonnullable_bounded_vector_of_handles) |
| RUN_TEST(encode_present_nullable_bounded_vector_of_handles) |
| RUN_TEST(encode_absent_nonnullable_bounded_vector_of_handles) |
| RUN_TEST(encode_absent_nullable_bounded_vector_of_handles) |
| RUN_TEST(encode_present_nonnullable_bounded_vector_of_handles_short_error) |
| RUN_TEST(encode_present_nullable_bounded_vector_of_handles_short_error) |
| END_TEST_CASE(vectors) |
| |
| BEGIN_TEST_CASE(unions) |
| RUN_TEST(encode_bad_tagged_union_error) |
| RUN_TEST(encode_single_armed_present_nonnullable_union) |
| RUN_TEST(encode_many_armed_present_nonnullable_union) |
| RUN_TEST(encode_single_armed_present_nullable_union) |
| RUN_TEST(encode_many_armed_present_nullable_union) |
| RUN_TEST(encode_single_armed_absent_nullable_union) |
| RUN_TEST(encode_many_armed_absent_nullable_union) |
| END_TEST_CASE(unions) |
| |
| BEGIN_TEST_CASE(structs) |
| RUN_TEST(encode_nested_nonnullable_structs) |
| RUN_TEST(encode_nested_nullable_structs) |
| RUN_TEST(encode_nested_struct_recursion_too_deep_error) |
| END_TEST_CASE(structs) |
| |
| } // namespace |
| } // namespace fidl |