| // Copyright 2021 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. |
| |
| // Tests tables whose fields are inlined into the envelope in the wire |
| // format. |
| success("TableFieldInlined") { |
| value = TableFieldInlinedStruct { |
| t: TableFieldInlined { |
| f: 123, |
| }, |
| }, |
| bytes = { |
| v1 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| num(8):4, num(0):4, |
| repeat(0xff):8, |
| |
| num(123):8, |
| ], |
| v2 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| num(123):4, num(0):2, num(1):2, |
| ] |
| } |
| } |
| |
| // Tests a table whose handle field is inlined into the envelope in the wire |
| // format. |
| success("TableFieldInlinedHandle") { |
| handle_defs = { |
| #0 = channel(), |
| }, |
| value = TableFieldInlinedHandleStruct { |
| t: TableFieldInlinedHandle { |
| f: #0, |
| }, |
| }, |
| bytes = { |
| v1 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| num(8):4, num(1):4, |
| repeat(0xff):8, |
| |
| repeat(0xff):4, padding:4, |
| ], |
| v2 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| repeat(0xff):4, num(1):2, num(1):2, |
| ] |
| }, |
| handles = { |
| v1, v2 = [#0], |
| } |
| } |
| |
| // A field that would normally be inlined is empty. |
| // This tests logic checking that values are inlined in the correct situations. |
| success("TableFieldInlinedReserved") { |
| value = TableFieldInlinedStruct { |
| t: TableFieldInlined { |
| 2: { |
| bytes = [num(123):8], |
| } |
| }, |
| }, |
| bytes = { |
| v2 = [ |
| num(2):8, |
| repeat(0xff):8, |
| |
| num(0):4, num(0):2, num(0):2, |
| num(8):4, num(0):2, num(0):2, |
| num(123):8, |
| ] |
| } |
| } |
| |
| // Tests tables whose fields are stored out of line in the wire format. |
| success("TableFieldOutOfLine") { |
| value = TableFieldOutOfLineStruct { |
| t: TableFieldOutOfLine { |
| f: 123, |
| }, |
| }, |
| bytes = { |
| v1 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| num(8):4, num(0):4, |
| repeat(0xff):8, |
| |
| num(123):8, |
| ], |
| v2 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| num(8):4, num(0):2, num(0):2, |
| |
| num(123):8, |
| ] |
| } |
| } |
| |
| // Tests a table in which a value is inlined into an unknown field. |
| success("TableFieldUnknownInlined") { |
| value = TableFieldUnknownStruct { |
| t: TableFieldUnknown { |
| 1: { |
| bytes = [num(123):4], |
| } |
| }, |
| }, |
| bytes = { |
| v2 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| num(123):4, num(0):2, num(1):2, |
| ] |
| } |
| } |
| |
| // Tests a table in which a handle value is inlined into an unknown field. |
| success("TableFieldUnknownInlinedHandle") { |
| handle_defs = { |
| #0 = channel(), |
| }, |
| value = TableFieldUnknownResourceStruct { |
| t: TableFieldUnknownResource { |
| 1: { |
| bytes = [repeat(0xff):4], |
| handles = [#0], |
| } |
| }, |
| }, |
| bytes = { |
| v2 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| repeat(0xff):4, num(1):2, num(1):2, |
| ] |
| }, |
| handles = { |
| v2 = [#0], |
| } |
| } |
| |
| // Tests a table in which a value is stored out of line in an unknown field. |
| success("TableFieldUnknownOutOfLine") { |
| value = TableFieldUnknownStruct { |
| t: TableFieldUnknown { |
| 1: { |
| bytes = [num(123):8], |
| }, |
| }, |
| }, |
| bytes = { |
| v1 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| num(8):4, num(0):4, |
| repeat(0xff):8, |
| |
| num(123):8, |
| ], |
| v2 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| num(8):4, num(0):2, num(0):2, |
| |
| num(123):8, |
| ] |
| } |
| } |
| |
| // Tests decode of a value in a table that can be represented inline in the |
| // envelope but is incorrectly using the out of line representation. |
| decode_failure("TableOutOfLineEnvelopeWhenInlineRequired") { |
| bindings_allowlist = [go,rust,dart], |
| type = TableFieldInlinedStruct, |
| bytes = { |
| v2 = [ |
| num(1):8, |
| repeat(0xff):8, |
| |
| num(8):4, num(0):2, num(0):2, |
| |
| num(123):8, |
| ] |
| }, |
| err = INVALID_INLINE_BIT_IN_ENVELOPE, |
| } |
| |
| // Test table with a 2^64-1 count, exceeding the 32-bit limit from RFC-0059. |
| decode_failure("TableCountExceedsLimitByALot") { |
| // TODO(fxbug.dev/82167): Go and Dart all panic and don't return proper errors. |
| bindings_denylist = [go, dart], |
| type = StructOfEmptyTable, |
| bytes = { |
| v1, v2 = [ |
| num(0xffffffffffffffff):8, // table field count |
| repeat(0xff):8, // presence marker |
| ] |
| }, |
| err = COUNT_EXCEEDS_LIMIT, |
| } |
| |
| // Test table with a 2^32 count, exceeding the 32-bit limit from RFC-0059. |
| decode_failure("TableCountExceedsLimitByOne") { |
| // TODO(fxbug.dev/82167): Go and Dart all panic and don't return proper errors. |
| bindings_denylist = [go, dart], |
| type = StructOfEmptyTable, |
| bytes = { |
| v1, v2 = [ |
| num(0x100000000):8, // table field count |
| repeat(0xff):8, // presence marker |
| ] |
| }, |
| err = COUNT_EXCEEDS_LIMIT, |
| } |
| |
| // Test table with count that exceeds the total message size. Bindings should |
| // explicitly check for this to avoid allocating huge tables before failing. |
| decode_failure("TableCountExceedsTotalMessageSize") { |
| type = StructOfEmptyTable, |
| bytes = { |
| v1, v2 = [ |
| num(25):8, // table field count (invalid, should be 8) |
| repeat(0xff):8, // presence marker |
| repeat(0xab):8, // table data |
| ] |
| }, |
| err = TOO_FEW_BYTES, |
| } |
| |
| // Test table with count that exceeds the remainder of the message size. |
| // Bindings should not explicitly check for this, but it should still fail. |
| decode_failure("TableCountExceedsRemainingMessageSize") { |
| type = StructOfEmptyTable, |
| bytes = { |
| v1, v2 = [ |
| num(9):8, // table field count (invalid, should be 8) |
| repeat(0xff):8, // presence marker |
| repeat(0xab):8, // table data |
| ] |
| }, |
| err = TOO_FEW_BYTES, |
| } |