| // 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. |
| |
| success("VectorWithLimit_randomly_generated") { |
| value = VectorWithLimit{ |
| v: [113, 200], |
| }, |
| bytes = { |
| v2 = [ |
| num(2):8, repeat(0xFF):8, // v length, presence |
| 113, 200, // v |
| padding:6, |
| ], |
| }, |
| } |
| |
| success("VectorWrapper_randomly_generated") { |
| value = VectorWrapper{ |
| v: [218, 190, 69, 67, 101, 72, 44, 22], |
| }, |
| bytes = { |
| v2 = [ |
| num(8):8, repeat(0xFF):8, // v length, presence |
| // v |
| 218, 190, 69, 67, 101, 72, 44, 22, |
| ], |
| }, |
| } |
| |
| encode_failure("VectorExceedsLimit") { |
| value = VectorWithLimit{ |
| v: [1, 2, 3], // exceeds the string length |
| }, |
| err = COUNT_EXCEEDS_LIMIT, |
| } |
| |
| decode_failure("EmptyVectorWithNullPtrBody") { |
| // TODO(https://fxbug.dev/42170062) Rust does not produce the correct error. |
| bindings_denylist = [rust], |
| type = VectorWrapper, |
| bytes = { |
| v2 = [ |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // length of vector data |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // invalid null pointer to content |
| ], |
| }, |
| err = NON_NULLABLE_TYPE_WITH_NULL_VALUE, |
| } |
| |
| success("EmptyOptionalVectorWithNullPtrBody") { |
| value = OptionalVectorWrapper{ |
| v: null, |
| }, |
| bytes = { |
| v2 = [ |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // length of vector data |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // invalid null pointer to content |
| ], |
| }, |
| } |
| |
| decode_failure("NonEmptyVectorWithNullPtrBody") { |
| // TODO(https://fxbug.dev/42170063) Fix this on dart. |
| bindings_denylist = [dart], |
| type = VectorWrapper, |
| bytes = { |
| v2 = [ |
| 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // length of vector data |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // invalid null pointer to content |
| ], |
| }, |
| err = NON_EMPTY_VECTOR_WITH_NULL_BODY, |
| } |
| |
| decode_failure("NonEmptyOptionalVectorWithNullPtrBody") { |
| // TODO(https://fxbug.dev/42170063) Fix this on dart. |
| bindings_denylist = [dart], |
| type = OptionalVectorWrapper, |
| bytes = { |
| v2 = [ |
| 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // length of vector data |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // invalid null pointer to content |
| ], |
| }, |
| err = NON_EMPTY_VECTOR_WITH_NULL_BODY, |
| } |
| |
| decode_failure("VectorWrongPointerValue") { |
| // TODO(https://fxbug.dev/42170063) Fix this on dart. |
| bindings_denylist = [dart], |
| type = VectorWrapper, |
| bytes = { |
| v2 = [ |
| 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // length of vector data |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // invalid pointer to content |
| ], |
| }, |
| err = INVALID_PRESENCE_INDICATOR, |
| } |
| |
| decode_failure("OptionalVectorWrongPointerValue") { |
| // TODO(https://fxbug.dev/42170063) Fix this on dart. |
| bindings_denylist = [dart], |
| type = OptionalVectorWrapper, |
| bytes = { |
| v2 = [ |
| 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // length of vector data |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // invalid pointer to content |
| ], |
| }, |
| err = INVALID_PRESENCE_INDICATOR, |
| } |
| |
| // Test vector with a 2^64-1 count, exceeding the 32-bit limit from RFC-0059. |
| decode_failure("VectorCountExceedsLimitByALot") { |
| type = VectorWrapper, |
| bytes = { |
| v2 = [ |
| num(0xffffffffffffffff):8, // length of vector data |
| repeat(0xff):8, // presence marker |
| ], |
| }, |
| err = VECTOR_COUNT_EXCEEDS_32_BIT_LIMIT, |
| } |
| |
| // Test vector with a 2^32 count, exceeding the 32-bit limit from RFC-0059. |
| decode_failure("VectorCountExceedsLimitByOne") { |
| type = VectorWrapper, |
| bytes = { |
| v2 = [ |
| num(0x100000000):8, // length of vector data |
| repeat(0xff):8, // presence marker |
| ], |
| }, |
| err = VECTOR_COUNT_EXCEEDS_32_BIT_LIMIT, |
| } |
| |
| // Test vector with count that exceeds the total message size. Bindings should |
| // explicitly check for this to avoid allocating huge vectors before failing. |
| decode_failure("VectorCountExceedsTotalMessageSize") { |
| type = VectorWrapper, |
| bytes = { |
| v2 = [ |
| num(25):8, // length of vector data (invalid, should be 8) |
| repeat(0xff):8, // presence marker |
| repeat(0xab):8, // vector data |
| ], |
| }, |
| err = TOO_FEW_BYTES, |
| } |
| |
| // Test vector with count that exceeds the remainder of the message size. |
| // Bindings should not explicitly check for this, but it should still fail. |
| decode_failure("VectorCountExceedsRemainingMessageSize") { |
| type = VectorWrapper, |
| bytes = { |
| v2 = [ |
| num(9):8, // length of vector data (invalid, should be 8) |
| repeat(0xff):8, // presence marker |
| repeat(0xab):8, // vector data |
| ], |
| }, |
| err = TOO_FEW_BYTES, |
| } |
| |
| success("EmptyByteVector") { |
| value = VectorWrapper{ |
| v: [], |
| }, |
| bytes = { |
| v2 = [ |
| num(0):8, |
| repeat(0xff):8, |
| ], |
| }, |
| } |
| |
| // When iovecs are used to write vectors, special handling is needed |
| // when the contents is not 8-byte aligned. |
| // Depending on the implementation, this may or may not take place |
| // for vectors < 8 bytes in size, but it is important to check because |
| // this is an edge case. |
| success("SmallVectorNon8ByteAligned") { |
| value = VectorWrapper{ |
| v: [1, 2, 3], |
| }, |
| bytes = { |
| v2 = [ |
| num(3):8, |
| repeat(0xff):8, |
| |
| 0x01, 0x02, 0x03, padding:5, |
| ], |
| }, |
| } |
| |
| // When iovecs are used to write vectors, special handling is needed |
| // when the contents is not 8-byte aligned. This checks the "boundary" |
| // where the vector becomes 8-byte aligned on a small vector. |
| success("SmallVector8ByteAligned") { |
| value = VectorWrapper{ |
| v: [1, 2, 3, 4, 5, 6, 7, 8], |
| }, |
| bytes = { |
| v2 = [ |
| num(8):8, |
| repeat(0xff):8, |
| |
| 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, |
| ], |
| }, |
| } |
| |
| // When iovecs are used to write vectors, special handling is needed |
| // when the contents is not 8-byte aligned. Sometimes these optimizations |
| // are disabled for small vectors, so test a larger vector. |
| success("LargeVectorNon8ByteAligned") { |
| value = VectorWrapper{ |
| v: [repeat(1):514], |
| }, |
| bytes = { |
| v2 = [ |
| num(514):8, |
| repeat(0xff):8, |
| |
| repeat(0x01):514, padding:6, |
| ], |
| }, |
| } |
| |
| // When iovecs are used to write vectors, special handling is needed |
| // when the contents is not 8-byte aligned. This checks the "boundary" |
| // where the vector becomes 8-byte aligned on a large vector. |
| success("LargeVector8ByteAligned") { |
| value = VectorWrapper{ |
| v: [repeat(1):512], |
| }, |
| bytes = { |
| v2 = [ |
| num(512):8, |
| repeat(0xff):8, |
| |
| repeat(0x01):512, |
| ], |
| }, |
| } |
| |
| success("VectorOfByteVector") { |
| value = VectorOfByteVector{ |
| v: [ |
| [1, 2, 3], |
| [4, 5], |
| [6, 7, 8, 9], |
| ], |
| }, |
| bytes = { |
| v2 = [ |
| // vector primary object's length, presence indicator |
| num(3):8, repeat(0xff):8, |
| |
| // v[0] length, presence |
| num(3):8, repeat(0xff):8, |
| |
| // v[1] length, presence |
| num(2):8, repeat(0xff):8, |
| |
| // v[2] length, presence |
| num(4):8, repeat(0xff):8, |
| |
| // v[0] |
| num(1):1, num(2):1, num(3):1, padding:5, |
| |
| // v[1] |
| num(4):1, num(5):1, padding:6, |
| |
| // v[2] |
| num(6):1, num(7):1, num(8):1, num(9):1, padding:4, |
| ], |
| }, |
| } |
| |
| success("VectorOfStrings_AFewStrings") { |
| value = VectorOfStrings{ |
| v: [ |
| "hello, world!", |
| "this is fine", |
| "bbbbbbbb", |
| "aaa", |
| ], |
| }, |
| bytes = { |
| v2 = [ |
| // vector primary object's length, presence indicator |
| num(4):8, repeat(0xff):8, |
| |
| // v[0] length, presence |
| num(13):8, repeat(0xff):8, |
| |
| // v[1] length, presence |
| num(12):8, repeat(0xff):8, |
| |
| // v[2] length, presence |
| num(8):8, repeat(0xff):8, |
| |
| // v[3] length, presence |
| num(3):8, repeat(0xff):8, |
| |
| // v[0] "hello, world!" |
| 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, |
| 0x6f, 0x72, 0x6c, 0x64, 0x21, padding:3, |
| |
| // v[1] "this is fine" |
| 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, |
| 0x66, 0x69, 0x6e, 0x65, padding:4, |
| |
| // v[2] "bbbbbbbb" |
| repeat(0x62):8, |
| |
| // v[3] "aaa" |
| 0x61, 0x61, 0x61, padding:5, |
| ], |
| }, |
| } |
| |
| success("LotsOfVectors_AFewVectors") { |
| value = LotsOfVectors{ |
| v1: [1, 2], |
| v2: [3, 3], |
| v3: [5, 6, 7, 8], |
| v4: ["hello, world!", "this is fine", "aaa"], |
| v5: [-1, -2], |
| v6: [-3, -4, -5], |
| v7: [-6, -7, -8, -9], |
| v8: [-10], |
| v9: [true, false, true], |
| }, |
| bytes = { |
| v2 = [ |
| // vector lengths & presences |
| num(2):8, repeat(0xff):8, // v1 |
| num(2):8, repeat(0xff):8, // v2 |
| num(4):8, repeat(0xff):8, // v3 |
| num(3):8, repeat(0xff):8, // v4 |
| num(2):8, repeat(0xff):8, // v5 |
| num(3):8, repeat(0xff):8, // v6 |
| num(4):8, repeat(0xff):8, // v7 |
| num(1):8, repeat(0xff):8, // v8 |
| num(3):8, repeat(0xff):8, // v9 |
| |
| // v1 contents + padding |
| num(1):2, num(2):2, padding:4, |
| |
| // v2 contents |
| num(3):4, num(3):4, |
| |
| // v3 contents |
| num(5):8, num(6):8, num(7):8, num(8):8, |
| |
| // v4 lengths and presences |
| num(13):8, repeat(0xff):8, // v4[0] |
| num(12):8, repeat(0xff):8, // v4[1] |
| num(3):8, repeat(0xff):8, // v4[2] |
| |
| // v4[0] "hello, world!" |
| 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, |
| 0x6f, 0x72, 0x6c, 0x64, 0x21, padding:3, |
| |
| // v4[1] "this is fine" |
| 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, |
| 0x66, 0x69, 0x6e, 0x65, padding:4, |
| |
| // v4[2] "aaa" |
| 0x61, 0x61, 0x61, padding:5, |
| |
| // v5 contents |
| num(-1):1, num(-2):1, padding:6, |
| |
| // v6 contents |
| num(-3):2, num(-4):2, num(-5):2, padding:2, |
| |
| // v7 contents |
| num(-6):4, num(-7):4, num(-8):4, num(-9):4, |
| |
| // v8 contents |
| num(-10):8, |
| |
| // v9 contents |
| 0x01, 0x00, 0x01, padding:5, |
| ], |
| }, |
| } |
| |
| // The kernel is optimized for at most 16 iovecs, so typically bindings that support |
| // iovecs use this number as a limit. Binding handling of iovecs is implementation |
| // specific, but in many cases this test will result in exactly 16 iovecs |
| // (1 for primary object and 1 for each of the 15 byte vectors). |
| success("ByteVectors15") { |
| // TODO(https://fxbug.dev/42052020) Fix for CPP / HLCPP. |
| bindings_denylist = [cpp, hlcpp], |
| value = VectorOfByteVector{ |
| v: [ |
| [repeat(1):512], |
| [repeat(2):512], |
| [repeat(3):512], |
| [repeat(4):512], |
| [repeat(5):512], |
| [repeat(6):512], |
| [repeat(7):512], |
| [repeat(8):512], |
| [repeat(9):512], |
| [repeat(10):512], |
| [repeat(11):512], |
| [repeat(12):512], |
| [repeat(13):512], |
| [repeat(14):512], |
| [repeat(15):512], |
| ], |
| }, |
| bytes = { |
| v2 = [ |
| num(15):8, |
| repeat(0xff):8, |
| |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| |
| repeat(1):512, |
| repeat(2):512, |
| repeat(3):512, |
| repeat(4):512, |
| repeat(5):512, |
| repeat(6):512, |
| repeat(7):512, |
| repeat(8):512, |
| repeat(9):512, |
| repeat(10):512, |
| repeat(11):512, |
| repeat(12):512, |
| repeat(13):512, |
| repeat(14):512, |
| repeat(15):512, |
| ], |
| }, |
| } |
| |
| // The kernel is optimized for at most 16 iovecs, so typically bindings that support |
| // iovecs use this number as a limit. Binding handling of iovecs is implementation |
| // specific, but in many cases this test will result in 17 iovecs |
| // (1 for primary object and 1 for each of the 16 byte vectors), which exercises |
| // the bindings ability to handle more iovecs than are supported by its iovec |
| // buffer. |
| success("ByteVectors16") { |
| // TODO(https://fxbug.dev/42052020) Fix for CPP / HLCPP. |
| bindings_denylist = [cpp, hlcpp], |
| value = VectorOfByteVector{ |
| v: [ |
| [repeat(1):512], |
| [repeat(2):512], |
| [repeat(3):512], |
| [repeat(4):512], |
| [repeat(5):512], |
| [repeat(6):512], |
| [repeat(7):512], |
| [repeat(8):512], |
| [repeat(9):512], |
| [repeat(10):512], |
| [repeat(11):512], |
| [repeat(12):512], |
| [repeat(13):512], |
| [repeat(14):512], |
| [repeat(15):512], |
| [repeat(16):512], |
| ], |
| }, |
| bytes = { |
| v2 = [ |
| num(16):8, |
| repeat(0xff):8, |
| |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| num(512):8, |
| repeat(0xff):8, |
| |
| repeat(1):512, |
| repeat(2):512, |
| repeat(3):512, |
| repeat(4):512, |
| repeat(5):512, |
| repeat(6):512, |
| repeat(7):512, |
| repeat(8):512, |
| repeat(9):512, |
| repeat(10):512, |
| repeat(11):512, |
| repeat(12):512, |
| repeat(13):512, |
| repeat(14):512, |
| repeat(15):512, |
| repeat(16):512, |
| ], |
| }, |
| } |