[wasm-gc] More tests for type definition decoding

Bug: v8:7748
Change-Id: I463c7472ebaa5b4092b7f0e69e259abbf9c3bc06
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2390769
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69853}
This commit is contained in:
Jakob Kummerow 2020-09-11 18:55:24 +02:00 committed by Commit Bot
parent 149c7773e8
commit 30c57eb930
5 changed files with 149 additions and 9 deletions

View File

@ -254,13 +254,11 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
uint32_t depth_length;
uint32_t depth =
decoder->read_u32v<validate>(pc + 1, &depth_length, "depth");
// TODO(7748): Introduce a proper limit.
const uint32_t kMaxRttSubtypingDepth = 7;
if (!VALIDATE(depth <= kMaxRttSubtypingDepth)) {
if (!VALIDATE(depth <= kV8MaxRttSubtypingDepth)) {
decoder->errorf(pc,
"subtyping depth %u is greater than the maximum depth "
"%u supported by V8",
depth, kMaxRttSubtypingDepth);
depth, kV8MaxRttSubtypingDepth);
return kWasmBottom;
}
HeapType heap_type = read_heap_type<validate>(

View File

@ -1955,8 +1955,7 @@ class ModuleDecoderImpl : public Decoder {
}
const StructType* consume_struct(Zone* zone) {
// TODO(7748): Introduce a proper maximum.
uint32_t field_count = consume_count("field count", 999);
uint32_t field_count = consume_count("field count", kV8MaxWasmStructFields);
if (failed()) return nullptr;
ValueType* fields = zone->NewArray<ValueType>(field_count);
bool* mutabilities = zone->NewArray<bool>(field_count);

View File

@ -399,9 +399,16 @@ class ValueType {
}
private:
using KindField = base::BitField<Kind, 0, 5>;
using HeapTypeField = base::BitField<uint32_t, 5, 20>;
using DepthField = base::BitField<uint8_t, 25, 7>;
static constexpr int kKindBits = 5;
static constexpr int kHeapTypeBits = 20;
static constexpr int kDepthBits = 7;
STATIC_ASSERT(kV8MaxWasmTypes < (1u << kHeapTypeBits));
// Note: we currently conservatively allow only 5 bits, but have room to
// store 7, so we can raise the limit if needed.
STATIC_ASSERT(kV8MaxRttSubtypingDepth < (1u << kDepthBits));
using KindField = base::BitField<Kind, 0, kKindBits>;
using HeapTypeField = KindField::Next<uint32_t, kHeapTypeBits>;
using DepthField = HeapTypeField::Next<uint8_t, kDepthBits>;
constexpr explicit ValueType(uint32_t bit_field) : bit_field_(bit_field) {}

View File

@ -48,6 +48,10 @@ constexpr size_t kV8MaxWasmTableInitEntries = 10000000;
constexpr size_t kV8MaxWasmTables = 1;
constexpr size_t kV8MaxWasmMemories = 1;
// GC proposal. These limits are not standardized yet.
constexpr size_t kV8MaxWasmStructFields = 999;
constexpr uint32_t kV8MaxRttSubtypingDepth = 31;
static_assert(kV8MaxWasmTableSize <= 4294967295, // 2^32 - 1
"v8 should not exceed WebAssembly's non-web embedding limits");
static_assert(kV8MaxWasmTableInitEntries <= kV8MaxWasmTableSize,

View File

@ -832,6 +832,138 @@ TEST_F(WasmModuleVerifyTest, RttSubGlobalTypeError) {
"(rtt 2 i31)");
}
TEST_F(WasmModuleVerifyTest, InvalidStructTypeDef) {
WASM_FEATURE_SCOPE(reftypes);
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
static const byte all_good[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmStructTypeCode, // --
U32V_1(1), // field count
kLocalI32, // perfectly valid field type
1)}; // mutability
EXPECT_VERIFIES(all_good);
static const byte invalid_field_type[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmStructTypeCode, // --
U32V_1(1), // field count
kWasmArrayTypeCode, // bogus field type
1)}; // mutability
EXPECT_FAILURE_WITH_MSG(invalid_field_type, "invalid value type");
static const byte field_type_oob_ref[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmStructTypeCode, // --
U32V_1(1), // field count
kLocalOptRef, // field type: reference...
3, // ...to nonexistent type
1)}; // mutability
EXPECT_FAILURE_WITH_MSG(field_type_oob_ref, "Type index 3 is out of bounds");
static const byte field_type_invalid_ref[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmStructTypeCode, // --
U32V_1(1), // field count
kLocalOptRef, // field type: reference...
U32V_4(1234567), // ...to a type > kV8MaxWasmTypes
1)}; // mutability
EXPECT_FAILURE_WITH_MSG(field_type_invalid_ref, "greater than the maximum");
static const byte field_type_invalid_ref2[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmStructTypeCode, // --
U32V_1(1), // field count
kLocalOptRef, // field type: reference...
kLocalI32, // ...to a non-referenceable type
1)}; // mutability
EXPECT_FAILURE_WITH_MSG(field_type_invalid_ref2, "Unknown heap type");
static const byte not_enough_field_types[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmStructTypeCode, // --
U32V_1(2), // field count
kLocalI32, // field type 1
1)}; // mutability 1
EXPECT_FAILURE_WITH_MSG(not_enough_field_types, "expected 1 byte");
static const byte not_enough_field_types2[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmStructTypeCode, // --
U32V_1(2), // field count
kLocalI32, // field type 1
1, // mutability 1
kLocalI32)}; // field type 2
EXPECT_FAILURE_WITH_MSG(not_enough_field_types2, "expected 1 byte");
static const byte invalid_mutability[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmStructTypeCode, // --
U32V_1(1), // field count
kLocalI32, // field type
2)}; // invalid mutability value
EXPECT_FAILURE_WITH_MSG(invalid_mutability, "invalid mutability");
}
TEST_F(WasmModuleVerifyTest, InvalidArrayTypeDef) {
WASM_FEATURE_SCOPE(reftypes);
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
static const byte all_good[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmArrayTypeCode, // --
kLocalI32, // perfectly valid field type
1)}; // mutability
EXPECT_VERIFIES(all_good);
static const byte invalid_field_type[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmArrayTypeCode, // --
kWasmArrayTypeCode, // bogus field type
1)}; // mutability
EXPECT_FAILURE_WITH_MSG(invalid_field_type, "invalid value type");
static const byte field_type_oob_ref[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmArrayTypeCode, // --
kLocalOptRef, // field type: reference...
3, // ...to nonexistent type
1)}; // mutability
EXPECT_FAILURE_WITH_MSG(field_type_oob_ref, "Type index 3 is out of bounds");
static const byte field_type_invalid_ref[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmArrayTypeCode, // --
kLocalOptRef, // field type: reference...
U32V_3(1234567), // ...to a type > kV8MaxWasmTypes
1)}; // mutability
EXPECT_FAILURE_WITH_MSG(field_type_invalid_ref, "Unknown heap type");
static const byte field_type_invalid_ref2[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmArrayTypeCode, // --
kLocalOptRef, // field type: reference...
kLocalI32, // ...to a non-referenceable type
1)}; // mutability
EXPECT_FAILURE_WITH_MSG(field_type_invalid_ref2, "Unknown heap type");
static const byte invalid_mutability[] = {
SECTION(Type, ENTRY_COUNT(1), // --
kWasmArrayTypeCode, // --
kLocalI32, // field type
2)}; // invalid mutability value
EXPECT_FAILURE_WITH_MSG(invalid_mutability, "invalid mutability");
static const byte invalid_mutability2[] = {
SECTION(Type,
ENTRY_COUNT(1), // --
kWasmArrayTypeCode, // --
kLocalI32, // field type
0)}; // immmutability (disallowed in MVP)
EXPECT_FAILURE_WITH_MSG(invalid_mutability2,
"immutable arrays are not supported");
}
TEST_F(WasmModuleVerifyTest, ZeroExceptions) {
static const byte data[] = {SECTION(Exception, ENTRY_COUNT(0))};
FAIL_IF_NO_EXPERIMENTAL_EH(data);