blob: dd28ccd2942a2d1fe07b6cee1b2bdcf5eff13344 [file] [log] [blame]
// Copyright 2019 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.
success("EmptyStruct") {
value = EmptyStruct {
},
bytes = {
v1, v2 = [
0x00, padding:7,
],
},
}
success("EmptyStructSandwich") {
value = EmptyStructSandwich {
before: "before",
es: EmptyStruct {},
after: "after",
},
bytes = {
v1, v2 = [
6, 0, 0, 0, 0, 0, 0, 0, // length of "before"
255, 255, 255, 255, 255, 255, 255, 255, // "before" is present
0, // empty struct zero field
0, 0, 0, 0, 0, 0, 0, // 7 bytes of padding after empty struct, to align to 64 bits
5, 0, 0, 0, 0, 0, 0, 0, // length of "after"
255, 255, 255, 255, 255, 255, 255, 255, // "after" is present
'b', 'e', 'f', 'o', 'r', 'e',
0, 0, // 2 bytes of padding after "before", to align to 64 bits
'a', 'f', 't', 'e', 'r', // "after" string
0, 0, 0, // 3 bytes of padding after "after", to align to 64 bits
],
},
}
success("Uint8Uint16Uint32Uint64") {
value = Uint8Uint16Uint32Uint64 {
f1: 0x01,
f2: 0x0203,
f3: 0x04050607,
f4: 0x08090a0b0c0d0e0f,
},
bytes = {
v1, v2 = [
0x01, // f1
0x00, // padding
0x03, 0x02, // f2
0x07, 0x06, 0x05, 0x04, // f3
0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, // f4
],
},
}
success("Uint64Uint32Uint16Uint8") {
// TODO(fxbug.dev/72895): Fix C/C++ bindings.
bindings_denylist = [fuzzer_corpus],
value = Uint64Uint32Uint16Uint8 {
f1: 0x08090a0b0c0d0e0f,
f2: 0x04050607,
f3: 0x0203,
f4: 0x01,
},
bytes = {
v1, v2 = [
0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, // f1
0x07, 0x06, 0x05, 0x04, // f2
0x03, 0x02, // f3
0x01, // f4
0x00, // padding
],
},
}
success("EmptyTable") {
value = StructOfEmptyTable {
table: EmptyTable {},
},
bytes = {
v1 = [
0, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
],
},
}
success("SimpleTableEmpty") {
value = StructOfSimpleTable {
table: SimpleTable {},
},
bytes = {
v1 = [
0, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
],
},
}
success("SimpleTableXAndY") {
value = StructOfSimpleTable {
table: SimpleTable {
x: 42,
y: 67,
},
},
bytes = {
v1 = [
5, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
67, 0, 0, 0, 0, 0, 0, 0, // field Y
],
},
}
success("SimpleTableJustX") {
value = StructOfSimpleTable {
table: SimpleTable {
x: 42,
},
},
bytes = {
v1 = [
1, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
],
},
}
success("SimpleTableJustY") {
value = StructOfSimpleTable {
table: SimpleTable {
y: 67,
},
},
bytes = {
v1 = [
5, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
67, 0, 0, 0, 0, 0, 0, 0, // field Y
],
},
}
success("TableWithStringAndVectorNoVectorContent") {
value = StructOfTableWithStringAndVector {
table: TableWithStringAndVector {
foo: "hello",
bar: 27,
},
},
bytes = {
v1 = [
2, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
24, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // envelope 1: alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // envelope 2: alloc present
5, 0, 0, 0, 0, 0, 0, 0, // element 1: length
255, 255, 255, 255, 255, 255, 255, 255, // element 1: alloc present
104, 101, 108, 108, 111, 0, 0, 0, // element 1: hello
27, 0, 0, 0, 0, 0, 0, 0, // element 2: value
],
},
}
// TODO(fxbug.dev/7948): Create test with TableWithStringAndVectorHasVectorContent.
success("SimpleTableThenUint64") {
value = SimpleTableThenUint64 {
table: SimpleTable {
x: 42,
y: 67,
},
number: 0xdeadbeefdeadbeef,
},
bytes = {
v1 = [
5, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, // uint64 number
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
67, 0, 0, 0, 0, 0, 0, 0, // field Y
],
},
}
success("ReverseOrdinalTable") {
value = StructOfReverseOrdinalTable {
table: ReverseOrdinalTable {
x: 0xaa,
y: 0xbb,
z: 0xcc,
},
},
bytes = {
v1 = [
// table
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // max ordinal 4
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
// z envelope (ordinal 1)
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 bytes, 0 handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
// y envelope (ordinal 2)
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 bytes, 0 handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
// empty envelope (reserved ordinal 3)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 bytes, 0 handles
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // null
// x envelope (ordinal 4)
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 bytes, 0 handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // z
0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // y
0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // x
],
},
}
success("TableWithGaps") {
value = StructOfTableWithGaps {
table: TableWithGaps {
second: 1,
fourth: 2,
},
},
bytes = {
v1 = [
num(4):8, repeat(0xff):8, // max ordinal, present
num(0):4, num(0):4, repeat(0x00):8, // envelope #1: empty
num(8):4, num(0):4, repeat(0xff):8, // envelope #2: second
num(0):4, num(0):4, repeat(0x00):8, // envelope #3: empty
num(8):4, num(0):4, repeat(0xff):8, // envelope #2: fourth
num(1):4, padding:4, // second
num(2):4, padding:4, // fourth
],
},
}
decode_success("ValueTableUnknownReservedDropped") {
// LLCPP is the only binding that does not store unknowns.
bindings_allowlist = [llcpp],
bytes = {
v1 = [
5, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
1, 2, 3, 4, 5, 6, 7, 8, // 8 unknown bytes for envelope 3
67, 0, 0, 0, 0, 0, 0, 0, // field Y
],
},
value = StructOfSimpleTable {
table: SimpleTable {
x: 42,
y: 67,
},
},
}
decode_success("ResourceTableUnknownReservedDropped") {
// LLCPP is the only binding that does not store unknowns.
bindings_allowlist = [llcpp],
bytes = {
v1 = [
5, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
1, 2, 3, 4, 5, 6, 7, 8, // 8 unknown bytes for envelope 3
67, 0, 0, 0, 0, 0, 0, 0, // field Y
],
},
value = StructOfSimpleResourceTable {
table: SimpleResourceTable {
x: 42,
y: 67,
},
},
}
success("ValueTableUnknownReservedStored") {
// LLCPP is tested in the ValueTableUnknownReservedDropped test
bindings_denylist = [llcpp],
bytes = {
v1 = [
5, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
1, 2, 3, 4, 5, 6, 7, 8, // 8 unknown bytes for envelope 3
67, 0, 0, 0, 0, 0, 0, 0, // field Y
],
},
value = StructOfSimpleTable {
table: SimpleTable {
x: 42,
y: 67,
3: {
bytes = [1, 2, 3, 4, 5, 6, 7, 8]
},
},
},
}
success("ResourceTableUnknownReservedStored") {
// LLCPP is tested in the ResourceTableUnknownReservedDropped test
bindings_denylist = [llcpp],
bytes = {
v1 = [
5, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
1, 2, 3, 4, 5, 6, 7, 8, // 8 unknown bytes for envelope 3
67, 0, 0, 0, 0, 0, 0, 0, // field Y
],
},
value = StructOfSimpleResourceTable {
table: SimpleResourceTable {
x: 42,
y: 67,
3: {
bytes = [1, 2, 3, 4, 5, 6, 7, 8]
},
},
},
}
decode_success("ValueTableUnknownTrailingDropped") {
// LLCPP is the only binding that does not store unknowns.
bindings_allowlist = [llcpp],
bytes = {
v1 = [
6, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 6: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
67, 0, 0, 0, 0, 0, 0, 0, // field Y
1, 2, 3, 4, 5, 6, 7, 8, // 8 unknown bytes for envelope 6
],
},
value = StructOfSimpleTable {
table: SimpleTable {
x: 42,
y: 67,
},
},
}
decode_success("ResourceTableUnknownTrailingDropped") {
// LLCPP is the only binding that does not store unknowns.
bindings_allowlist = [llcpp],
bytes = {
v1 = [
6, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 6: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
67, 0, 0, 0, 0, 0, 0, 0, // field Y
1, 2, 3, 4, 5, 6, 7, 8, // 8 unknown bytes for envelope 6
],
},
value = StructOfSimpleResourceTable {
table: SimpleResourceTable {
x: 42,
y: 67,
},
},
}
success("ValueTableUnknownTrailingStored") {
// LLCPP is tested in the ValueTableUnknownTrailingDropped test
bindings_denylist = [llcpp],
bytes = {
v1 = [
6, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 6: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
67, 0, 0, 0, 0, 0, 0, 0, // field Y
1, 2, 3, 4, 5, 6, 7, 8, // 8 unknown bytes for envelope 6
],
},
value = StructOfSimpleTable {
table: SimpleTable {
x: 42,
y: 67,
6: {
bytes = [1, 2, 3, 4, 5, 6, 7, 8]
},
},
},
}
success("ResourceTableUnknownTrailingStored") {
// LLCPP is tested in the ResourceTableUnknownTrailingDropped test
bindings_denylist = [llcpp],
bytes = {
v1 = [
6, 0, 0, 0, 0, 0, 0, 0, // max ordinal
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
0, 0, 0, 0, 0, 0, 0, 0, // no alloc
8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
8, 0, 0, 0, 0, 0, 0, 0, // envelope 6: num bytes / num handles
255, 255, 255, 255, 255, 255, 255, 255, // alloc present
42, 0, 0, 0, 0, 0, 0, 0, // field X
67, 0, 0, 0, 0, 0, 0, 0, // field Y
1, 2, 3, 4, 5, 6, 7, 8, // 8 unknown bytes for envelope 6
],
},
value = StructOfSimpleResourceTable {
table: SimpleResourceTable {
x: 42,
y: 67,
6: {
bytes = [1, 2, 3, 4, 5, 6, 7, 8]
},
},
},
}
decode_success("ValueTableUnknownTrailingHandlesDropped") {
// LLCPP is the only binding that does not store unknowns.
bindings_allowlist = [llcpp],
handle_defs = {
#0 = event(),
#1 = event(),
#2 = event(),
},
value = StructOfSimpleTable {
table: SimpleTable {
y: 67,
},
},
bytes = {
v1 = [
num(6):8, // max ordinal
repeat(0xff):8, // alloc present
num(0):4, num(0):4, repeat(0):8, // absent envelope 1
num(0):4, num(0):4, repeat(0):8, // absent envelope 2
num(0):4, num(0):4, repeat(0):8, // absent envelope 3
num(0):4, num(0):4, repeat(0):8, // absent envelope 4
num(8):4, num(0):4, repeat(0xff):8, // envelope 5 (field Y)
num(24):4, num(3):4, repeat(0xff):8, // envelope 6 (unknown)
num(67):8, // field Y
repeat(0xab):20, padding:4, // unknown bytes
],
},
handles = {
v1 = [
#0, #1, #2,
]
}
}
decode_success("ResourceTableUnknownTrailingHandlesDropped") {
// LLCPP is the only binding that does not store unknowns.
bindings_allowlist = [llcpp],
handle_defs = {
#0 = event(),
#1 = event(),
#2 = event(),
},
value = StructOfSimpleResourceTable {
table: SimpleResourceTable {
y: 67,
},
},
bytes = {
v1 = [
num(6):8, // max ordinal
repeat(0xff):8, // alloc present
num(0):4, num(0):4, repeat(0):8, // absent envelope 1
num(0):4, num(0):4, repeat(0):8, // absent envelope 2
num(0):4, num(0):4, repeat(0):8, // absent envelope 3
num(0):4, num(0):4, repeat(0):8, // absent envelope 4
num(8):4, num(0):4, repeat(0xff):8, // envelope 5 (field Y)
num(24):4, num(3):4, repeat(0xff):8, // envelope 6 (unknown)
num(67):8, // field Y
repeat(0xab):20, padding:4, // unknown bytes
],
},
handles = {
v1 = [
#0, #1, #2,
]
}
}
decode_failure("ValueTableUnknownTrailingHandlesRejected") {
// LLCPP is tested in the ValueTableUnknownTrailingHandlesDropped test
bindings_denylist = [c, llcpp],
handle_defs = {
#0 = event(),
#1 = event(),
#2 = event(),
},
type = StructOfSimpleTable,
bytes = {
v1 = [
num(6):8, // max ordinal
repeat(0xff):8, // alloc present
num(0):4, num(0):4, repeat(0):8, // absent envelope 1
num(0):4, num(0):4, repeat(0):8, // absent envelope 2
num(0):4, num(0):4, repeat(0):8, // absent envelope 3
num(0):4, num(0):4, repeat(0):8, // absent envelope 4
num(8):4, num(0):4, repeat(0xff):8, // envelope 5 (field Y)
num(24):4, num(3):4, repeat(0xff):8, // envelope 6 (unknown)
num(67):8, // field Y
repeat(0xab):20, padding:4, // unknown bytes
],
},
handles = {
v1 = [
#0, #1, #2,
]
},
err = NON_RESOURCE_UNKNOWN_HANDLES,
}
success("ResourceTableUnknownTrailingHandlesStored") {
// LLCPP is tested in the ResourceTableUnknownTrailingHandlesDropped test
bindings_denylist = [llcpp],
handle_defs = {
#0 = event(),
#1 = event(),
#2 = event(),
},
value = StructOfSimpleResourceTable {
table: SimpleResourceTable {
y: 67,
6: {
bytes = [repeat(0xab):20, padding:4],
handles = [#0, #1, #2],
},
},
},
bytes = {
v1 = [
num(6):8, // max ordinal
repeat(0xff):8, // alloc present
num(0):4, num(0):4, repeat(0):8, // absent envelope 1
num(0):4, num(0):4, repeat(0):8, // absent envelope 2
num(0):4, num(0):4, repeat(0):8, // absent envelope 3
num(0):4, num(0):4, repeat(0):8, // absent envelope 4
num(8):4, num(0):4, repeat(0xff):8, // envelope 5 (field Y)
num(24):4, num(3):4, repeat(0xff):8, // envelope 6 (unknown)
num(67):8, // field Y
repeat(0xab):20, padding:4, // unknown bytes
],
},
handles = {
v1 = [
#0, #1, #2,
]
}
}
decode_failure("ValueTableUnknownBytesNonMultipleOf8") {
// TODO(fxbug.dev/80162): Check num_bytes%8==0 in Go.
bindings_denylist = [go],
type = StructOfSimpleTable,
bytes = {
v1 = [
num(2):8, // max ordinal
repeat(0xff):8, // alloc present
num(0):4, num(0):4, repeat(0):8, // absent envelope 1
num(20):4, num(0):4, repeat(0xff):8, // envelope 2 (unknown)
repeat(0xab):20, padding:4, // unknown bytes
],
},
err = INVALID_NUM_BYTES_IN_ENVELOPE,
}
decode_failure("ResourceTableUnknownBytesNonMultipleOf8") {
// TODO(fxbug.dev/80162): Check num_bytes%8==0 in Go.
bindings_denylist = [go],
type = StructOfSimpleResourceTable,
bytes = {
v1 = [
num(2):8, // max ordinal
repeat(0xff):8, // alloc present
num(0):4, num(0):4, repeat(0):8, // absent envelope 1
num(20):4, num(0):4, repeat(0xff):8, // envelope 2 (unknown)
repeat(0xab):20, padding:4, // unknown bytes
],
},
err = INVALID_NUM_BYTES_IN_ENVELOPE,
}
success("InlineXUnionInStruct") {
value = TestInlineXUnionInStruct {
before: "before",
xu: SampleXUnion {
u: 0xdeadbeef,
},
after: "after",
},
bytes = {
v1 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes + num handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // envelope data is present
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: xunion content
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // xunion envelope content (0xdeadbeef) + padding
// secondary object 3: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
v2 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x01, 0x00, // num bytes + num handles + inlined
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
},
}
success("OptionalXUnionInStructAbsent") {
value = TestOptionalXUnionInStruct {
before: "before",
// no SampleXUnion
after: "after",
},
bytes = {
v1 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes + num handles
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // envelope data is absent
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
v2 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes + num handles + not inlined
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
},
}
decode_failure("OptionalXUnionInStructAbsentInvalidNumBytes") {
type = TestOptionalXUnionInStruct,
bytes = {
v1 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes (invalid) + num handles
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // envelope data is absent
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
},
err = INVALID_NUM_BYTES_IN_ENVELOPE,
}
decode_failure("OptionalXUnionInStructAbsentInvalidNumHandles") {
type = TestOptionalXUnionInStruct,
bytes = {
v1 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // num bytes + num handles (invalid)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // envelope data is absent
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
},
err = INVALID_NUM_HANDLES_IN_ENVELOPE,
}
success("OptionalXUnionInStructPresent") {
value = TestOptionalXUnionInStruct {
before: "before",
xu: SampleXUnion {
u: 0xdeadbeef,
},
after: "after",
},
bytes = {
v1 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes + num handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // envelope data is present
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: xunion content
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // xunion envelope content (0xdeadbeef) + padding
// secondary object 3: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
v2 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x01, 0x00, // num bytes + num handles + inlined
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
},
}
decode_failure("OptionalXUnionInStructPresentZeroNumBytes") {
type = TestOptionalXUnionInStruct,
bytes = {
v1 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes (invalid) + num handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // envelope data is present
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: xunion content
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // xunion envelope content (0xdeadbeef) + padding
// secondary object 3: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
},
err = INVALID_NUM_BYTES_IN_ENVELOPE,
}
decode_failure("OptionalXUnionInStructPresentInvalidNumBytes") {
type = TestOptionalXUnionInStruct,
bytes = {
v1 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes (invalid) + num handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // envelope data is present
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: xunion content
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // xunion envelope content (0xdeadbeef) + padding
// secondary object 3: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
v2 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes (invalid) + num handles + not inlined
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: xunion content
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // xunion envelope content (0xdeadbeef) + padding
// secondary object 3: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
},
err = INVALID_NUM_BYTES_IN_ENVELOPE,
}
decode_failure("OptionalXUnionInStructPresentInvalidNumHandles") {
type = TestOptionalXUnionInStruct,
bytes = {
v1 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // num bytes + num handles (invalid)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // envelope data is present
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 2: xunion content
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // xunion envelope content (0xdeadbeef) + padding
// secondary object 3: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
v2 = [
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" presence
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0xef, 0xbe, 0xad, 0xde, 0x01, 0x00, 0x01, 0x00, // num bytes + num handles (invalid) + inlined
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" presence
// secondary object 1: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00,
// secondary object 32: "after"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00,
],
},
err = INVALID_NUM_HANDLES_IN_ENVELOPE,
}
success("XUnionInTableXUnionAbsent") {
value = TestXUnionInTable {
value: XUnionInTable {
before: "before",
// no SampleXUnion
after: "after",
},
},
bytes = {
v1 = [
// primary object
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // vector<envelope> element count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // vector<envelope> present
// secondary object 1: vector data
// vector[0]: envelope<string before>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" is present
// vector[1]: envelope<SampleXUnion xu>
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion is absent
// vector[2]: envelope<string after>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" is present
// secondary object 2: "before" length + pointer
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" present
// secondary object 3: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00, // "before"
// secondary object 4: "after" length + pointer
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" present
// secondary object 5: "before"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00, // "after"
],
},
}
decode_failure("XUnionInTableXUnionAbsentInvalidNumBytes") {
type = TestXUnionInTable,
bytes = {
v1 = [
// primary object
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // vector<envelope> element count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // vector<envelope> present
// secondary object 1: vector data
// vector[0]: envelope<string before>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" is present
// vector[1]: envelope<SampleXUnion xu>
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size (invalid) + handle count
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion is absent
// vector[2]: envelope<string after>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" is present
// secondary object 2: "before" length + pointer
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" present
// secondary object 3: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00, // "before"
// secondary object 4: "after" length + pointer
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" present
// secondary object 5: "before"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00, // "after"
],
},
err = INVALID_NUM_BYTES_IN_ENVELOPE,
}
decode_failure("XUnionInTableXUnionAbsentInvalidNumHandles") {
type = TestXUnionInTable,
bytes = {
v1 = [
// primary object
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // vector<envelope> element count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // vector<envelope> present
// secondary object 1: vector data
// vector[0]: envelope<string before>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" is present
// vector[1]: envelope<SampleXUnion xu>
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // size + handle (invalid) count
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion is absent
// vector[2]: envelope<string after>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" is present
// secondary object 2: "before" length + pointer
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" present
// secondary object 3: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00, // "before"
// secondary object 4: "after" length + pointer
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" present
// secondary object 5: "before"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00, // "after"
],
},
err = INVALID_NUM_HANDLES_IN_ENVELOPE,
}
success("XUnionInTableXUnionPresent") {
value = TestXUnionInTable {
value: XUnionInTable {
before: "before",
xu: SampleXUnion {
u: 0xdeadbeef,
},
after: "after",
},
},
bytes = {
v1 = [
// primary object
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // vector<envelope> element count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // vector<envelope> present
// secondary object 1: vector data
// vector[0]: envelope<string before>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" is present
// vector[1]: envelope<SampleXUnion xu>
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // xunion is present
// vector[2]: envelope<string after>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" is present
// secondary object 2: "before" length + pointer
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" present
// secondary object 3: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00, // "before"
// secondary object 4: xunion
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes + num handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // envelope data is present
// secondary object 5: xunion content
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // 0xdeadbeef + padding
// secondary object 6: "after" length + pointer
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" present
// secondary object 7: "before"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00, // "after"
],
},
}
decode_failure("XUnionInTableXUnionPresentZeroNumBytes") {
type = TestXUnionInTable,
bytes = {
v1 = [
// primary object
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // vector<envelope> element count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // vector<envelope> present
// secondary object 1: vector data
// vector[0]: envelope<string before>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" is present
// vector[1]: envelope<SampleXUnion xu>
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size (invalid) + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // xunion is present
// vector[2]: envelope<string after>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" is present
// secondary object 2: "before" length + pointer
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" present
// secondary object 3: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00, // "before"
// secondary object 4: xunion
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes + num handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // envelope data is present
// secondary object 5: xunion content
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // 0xdeadbeef + padding
// secondary object 6: "after" length + pointer
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" present
// secondary object 7: "before"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00, // "after"
],
},
err = INVALID_NUM_BYTES_IN_ENVELOPE,
}
decode_failure("XUnionInTableXUnionPresentInvalidNumBytes") {
type = TestXUnionInTable,
bytes = {
v1 = [
// primary object
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // vector<envelope> element count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // vector<envelope> present
// secondary object 1: vector data
// vector[0]: envelope<string before>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" is present
// vector[1]: envelope<SampleXUnion xu>
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size (invalid) + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // xunion is present
// vector[2]: envelope<string after>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" is present
// secondary object 2: "before" length + pointer
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" present
// secondary object 3: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00, // "before"
// secondary object 4: xunion
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes + num handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // envelope data is present
// secondary object 5: xunion content
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // 0xdeadbeef + padding
// secondary object 6: "after" length + pointer
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" present
// secondary object 7: "before"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00, // "after"
],
},
err = INVALID_NUM_BYTES_IN_ENVELOPE,
}
decode_failure("XUnionInTableXUnionPresentInvalidNumHandles") {
type = TestXUnionInTable,
bytes = {
v1 = [
// primary object
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // vector<envelope> element count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // vector<envelope> present
// secondary object 1: vector data
// vector[0]: envelope<string before>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" is present
// vector[1]: envelope<SampleXUnion xu>
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // size + handle (invalid) count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // xunion is present
// vector[2]: envelope<string after>
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // size + handle count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" is present
// secondary object 2: "before" length + pointer
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "before" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "before" present
// secondary object 3: "before"
'b', 'e', 'f', 'o', 'r', 'e', 0x00, 0x00, // "before"
// secondary object 4: xunion
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes + num handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // envelope data is present
// secondary object 5: xunion content
0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // 0xdeadbeef + padding
// secondary object 6: "after" length + pointer
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "after" length
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // "after" present
// secondary object 7: "before"
'a', 'f', 't', 'e', 'r', 0x00, 0x00, 0x00, // "after"
],
},
err = INVALID_NUM_HANDLES_IN_ENVELOPE,
}
success("StrictXUnion") {
value = TestStrictXUnionInStruct {
xu: SampleStrictXUnion {
u: 0xdeadbeef,
},
},
bytes = {
v1 = [
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xef,0xbe,0xad,0xde,0x00,0x00,0x00,0x00,
],
v2 = [
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xef,0xbe,0xad,0xde,0x00,0x00,0x01,0x00,
],
},
}
success("RecursiveVectorUnionStruct") {
// TODO(fxbug.dev/7644): Fix self-references and enable for Dart.
bindings_denylist = [dart, transformer],
value = RecursiveVectorUnionStruct {
u: RecursiveVectorUnion {
vec: [
RecursiveVectorUnion {
vec: [],
},
],
},
},
bytes = {
v1 = [
// primary object: outer union
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ordinal
0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // num bytes + num handles
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // envelope data is present
// secondary object 1: outer vector
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // size 1
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
// secondary object 2: inner union
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ordinal
0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // num bytes + num handles
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // envelope data is present
// secondary object 3: inner vector
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // size 0
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
],
v2 = [
// primary object: outer union
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ordinal
0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // num bytes + num handles
// secondary object 1: outer vector
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // size 1
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
// secondary object 2: inner union
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ordinal
0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // num bytes + num handles
// secondary object 3: inner vector
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // size 0
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
],
},
}
success("MutualRecursionUnionStruct") {
// TODO(fxbug.dev/7644): Fix self-references and enable for Dart.
bindings_denylist = [dart, transformer],
value = MutualRecursionUnionStruct {
u: MutualRecursionUnion {
s: MutualRecursionUnionStruct {
u: MutualRecursionUnion {
s: MutualRecursionUnionStruct {},
},
},
},
},
bytes = {
v1 = [
// primary object: outer union
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ordinal
0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // num bytes + num handles
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // envelope data is present
// secondary object 1: inner union
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ordinal
0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // num bytes + num handles
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // envelope data is present
// secondary object 2: null union
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ordinal
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // num bytes + num handles
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // envelope data is not present
],
v2 = [
// primary object: outer union
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ordinal
0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // num bytes + num handles
// secondary object 1: inner union
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ordinal
0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // num bytes + num handles
// secondary object 2: null union
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ordinal
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // num bytes + num handles + not inlined
],
},
}
success("AddEthernetDeviceRequest") {
value = TestAddEthernetDeviceRequest {
topological_path: "@/dev/sys/pci/00:03.0/e1000/ethernet",
config: InterfaceConfig {
name: "ethp0003",
ip_address_config: IpAddressConfig {
dhcp: true,
},
},
// TODO(fxbug.dev/7947): This should be a handle.
this_should_be_a_handle: 0xffffffff,
},
bytes = {
v1 = [
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // topological_path
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // topological_path
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // name
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // name
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subnet (dhcp ordinal)
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 bytes, 0 handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, // device (handle present)
0x40, 0x2f, 0x64, 0x65, 0x76, 0x2f, 0x73, 0x79, // @/dev/sy
0x73, 0x2f, 0x70, 0x63, 0x69, 0x2f, 0x30, 0x30, // s/pci/00
0x3a, 0x30, 0x33, 0x2e, 0x30, 0x2f, 0x65, 0x31, // :03.0/e1
0x30, 0x30, 0x30, 0x2f, 0x65, 0x74, 0x68, 0x65, // 000/ethe
0x72, 0x6e, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, // rnet
0x65, 0x74, 0x68, 0x70, 0x30, 0x30, 0x30, 0x33, // ethp0003
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // dhcp = true
],
},
}
success("FileGetAttrResponse") {
value = FileGetAttrResponse {
s: 0x7eadbeaf,
attributes: NodeAttributes {
mode: 0x962381a4,
id: 1,
content_size: 231,
storage_size: 231,
link_count: 1,
creation_time: 0x8877665544332211,
modification_time: 0x00ffeeddccbbaa99,
},
},
bytes = {
v1, v2 = [
0xaf, 0xbe, 0xad, 0x7e, 0x00, 0x00, 0x00, 0x00,
0xa4, 0x81, 0x23, 0x96, 0x00, 0x00, 0x00, 0x00,
1, 0, 0, 0, 0, 0, 0, 0,
231, 0, 0, 0, 0, 0, 0, 0,
231, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00,
],
},
}
// See comment in optionals.test.fidl for why this test case exists.
success("Optionals") {
value = StructWithOptionals {
s: EmptyStruct {
},
s2: EmptyStruct {
},
t: TableWithEmptyStruct {
s: EmptyStruct {},
},
xu: XUnionWithEmptyStruct {
s: EmptyStruct {},
},
xu2: XUnionWithEmptyStruct {
s: EmptyStruct {},
},
u: UnionWithEmptyStruct {
s: EmptyStruct {},
},
u2: UnionWithEmptyStruct {
s: EmptyStruct {},
},
},
bytes = {
v1 = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // EmptyStruct
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // EmptyStruct? present
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TableWithEmptyStruct length 1
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // XUnionWithEmptyStruct ordinal
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 bytes, 0 handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // XUnionWithEmptyStruct? ordinal
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 bytes, 0 handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // UnionWithEmptyStruct ordinal
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 bytes, 0 handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // UnionWithEmptyStruct? ordinal
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 bytes, 0 handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
// secondary objects
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // EmptyStruct
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // envelope 8 bytes, 0 handles
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // present
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // EmptyStruct (table t)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // EmptyStruct (xunion xu)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // EmptyStruct (xunion xu2)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // EmptyStruct (union u)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // EmptyStruct (union u2)
],
},
}
success("OutOfLinePaddingZeroed7") {
value = OutOfLinePaddingZeroed7{
a: Uint8Struct{
val: 0x01,
},
b: Uint64Struct{
val: 2,
},
},
bytes = {
v1, v2 = [
repeat(0xff):8, // a*
repeat(0xff):8, // b*
0x01, padding:7, // a + 7 padding
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // b
]
}
}
success("OutOfLinePaddingZeroed6") {
value = OutOfLinePaddingZeroed6{
a: Uint16Struct{
val: 0x0201,
},
b: Uint64Struct{
val: 3,
},
},
bytes = {
v1, v2 = [
repeat(0xff):8, // a*
repeat(0xff):8, // b*
0x01,0x02, padding:6, // a + 6 padding
0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // b
]
}
}
success("OutOfLinePaddingZeroed4") {
value = OutOfLinePaddingZeroed4{
a: Uint32Struct{
val: 0x04030201,
},
b: Uint64Struct{
val: 5,
},
},
bytes = {
v1, v2 = [
repeat(0xff):8, // a*
repeat(0xff):8, // b*
0x01,0x02,0x03,0x04, padding:4, // a + 4 padding
0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // b
]
}
}
success("Arrays") {
value = StructWithArrays {
arr_int: [1, 2,],
arr_string: ["a", "b",],
arr_nullable_string: ["c", null,],
arr_struct: [StructWithInt{x: 1,},StructWithInt{x: 2,},],
arr_nullable_struct: [null,StructWithInt{x: 0x01020304,},],
arr_arr_int: [[1, 2, 3,], [4, 5, 6,],],
},
bytes = {
v1, v2 = [
// primary object
0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00, // arr_int: 1, 2
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // arr_string: "a" size 1
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // "a" present
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "b" size 1
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // "b" present
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // arr_nullable_string: "c" size 1
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // "c" present
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // null size 0
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // null not present
0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00, // arr_struct: {x: 1}, {x: 2}
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // arr_nullable_struct: null not present
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // {x: 0x01020304} present
0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00, // arr_arr_int: 1, 2,
0x03,0x00,0x00,0x00,0x04,0x00,0x00,0x00, // 3, 4,
0x05,0x00,0x00,0x00,0x06,0x00,0x00,0x00, // 5, 6,
// secondary objects
0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "a"
0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "b"
0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "c"
0x04,0x03,0x02,0x01,0x00,0x00,0x00,0x00, // {x: 0x01020304} + padding
],
},
}
success("Vectors") {
value = StructWithVectors {
vec_empty: [],
vec_int: [1, 2,],
vec_string: ["a", "b",],
vec_nullable_string: [null, "c", null,],
vec_struct: [StructWithInt{x: 1,},],
vec_nullable_struct: [null, null, StructWithInt{x: 2,},],
vec_vec_int: [[1, 2,], [3,],],
},
bytes = {
v1, v2 = [
// primary object
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_empty: size 0
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_int: size 2
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_string: size 2
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_nullable_string: size 3
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_struct: size 1
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_nullable_struct: size 3
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_vec_int: size 2
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // present
// secondary objects
0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00, // vec_int: 1, 2
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_string: "a" size 1
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // "a" present
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "b" size 1
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // "b" present
0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "a"
0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "b"
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_nullable_string: null size 0
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // null not present
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "c" size 1
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // "c" present
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // null size 0
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // null not present
0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "c"
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_struct: {x: 1}
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_nullable_struct: null not present
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // null not present
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // {x: 2} present
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // {x: 2}
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // vec_vec_int: [1, 2] size 2
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // [1, 2] present
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // [3] size 1
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // [3] present
0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00, // [1, 2]
0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // [3]
],
},
}
// Test that bindings can use large arrays. Before const generics, Rust did not
// support arrays with more than 32 elements.
success("LargeArrays") {
value = LargeArrays {
a33: [
"first", null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, "last",
],
a100: [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
],
nested: [],
},
bytes = {
v1, v2 = [
num(5):8, repeat(0xff):8, // "first" length + present
repeat(0):496, // 31x length + absent (16)
num(4):8, repeat(0xff):8, // "last" length + present
// a100 array
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
padding:4,
num(0):8, repeat(0xff):8, // nested vector length + present
// "first" and "last" secondary objects
'f', 'i', 'r', 's', 't', padding:3,
'l', 'a', 's', 't', padding: 4,
],
},
}
// This tests the default input used in fidlviz:
// https://fuchsia.googlesource.com/fidl-misc/+/HEAD/fidlviz/
success("FidlvizDemo") {
// TODO(fxbug.dev/36441): Implement handles in all backends.
bindings_denylist = [c, llcpp],
handle_defs = {
#0 = event(),
},
value = FidlvizDemo {
// Integers
f1: 0, f2: -1, f3: 2, f4: 3, f5: 4,
// Other bases
f6: 0b1010, f7: 0xff, f8: 0o755,
// Floats
f9: 1.0, f10: 1.0e-8,
// Booleans
f11: true, f12: false,
// Strings
f13: "Hello 🌎\u0021",
f14: null, f15: "",
// Handles
f16: null, f17: #0,
// Arrays and vectors
f18: [12, 223, 0xff],
f19: [1.0, 2.0, 0.3],
f20: null,
f21: [],
// Bits and enums
f22: 0b111, f23: 42,
// Structs
f24: FidlvizStruct1 {},
f25: FidlvizStruct2 { x: 1 },
f26: null,
f27: FidlvizStruct2 { x: 42 },
// Tables
f28: FidlvizTable {},
f29: FidlvizTable { f1: true, f3: false },
// Unions
f30: null,
f31: FidlvizUnion { f7: "hi" },
},
bytes = {
v1 = [
0x00, 0xff, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0a, 0xff, 0xed, 0x01, 0x00, 0x00, 0x80, 0x3f,
0x3a, 0x8c, 0x30, 0xe2, 0x8e, 0x79, 0x45, 0x3e,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0x0c, 0xdf, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x07, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0xf0, 0x9f,
0x8c, 0x8e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xd3, 0x3f,
0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x68, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
],
},
handles = {
v1 = [ #0 ],
},
}