From 43ffb09247e1e48f021abb63131bedd449e55209 Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Mon, 27 Feb 2023 19:04:23 +0000 Subject: [PATCH] tint: validate max number of case selectors in a switch statement Bug: tint:1209 Change-Id: Id91901125e7caf9b8b0e297305c26587edaa44d9 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121741 Kokoro: Kokoro Reviewed-by: Ben Clayton --- .../resolver/control_block_validation_test.cc | 31 +++++++++++++++++++ src/tint/resolver/validator.cc | 8 +++++ 2 files changed, 39 insertions(+) diff --git a/src/tint/resolver/control_block_validation_test.cc b/src/tint/resolver/control_block_validation_test.cc index 2104321a18..ba7aa53490 100644 --- a/src/tint/resolver/control_block_validation_test.cc +++ b/src/tint/resolver/control_block_validation_test.cc @@ -561,5 +561,36 @@ TEST_F(ResolverControlBlockValidationTest, Switch_OverrideCondition_Fail) { EXPECT_EQ(r()->error(), "12:34 error: case selector must be a constant expression"); } +constexpr size_t kMaxSwitchCaseSelectors = 16383; + +TEST_F(ResolverControlBlockValidationTest, Switch_MaxSelectors_Valid) { + utils::Vector cases; + for (size_t i = 0; i < kMaxSwitchCaseSelectors - 1; ++i) { + cases.Push(Case(CaseSelector(Expr(i32(i))))); + } + cases.Push(DefaultCase()); + + auto* var = Var("a", ty.i32()); + auto* s = Switch("a", std::move(cases)); + WrapInFunction(var, s); + + EXPECT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverControlBlockValidationTest, Switch_MaxSelectors_Invalid) { + utils::Vector cases; + for (size_t i = 0; i < kMaxSwitchCaseSelectors; ++i) { + cases.Push(Case(CaseSelector(Expr(i32(i))))); + } + cases.Push(DefaultCase()); + + auto* var = Var("a", ty.i32()); + auto* s = Switch(Source{{12, 34}}, "a", std::move(cases)); + WrapInFunction(var, s); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), "12:34 error: switch statement has 16384 case selectors, max is 16383"); +} + } // namespace } // namespace tint::resolver diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc index 6ae5ce28f5..6419999635 100644 --- a/src/tint/resolver/validator.cc +++ b/src/tint/resolver/validator.cc @@ -77,6 +77,7 @@ namespace tint::resolver { namespace { constexpr size_t kMaxFunctionParameters = 255; +constexpr size_t kMaxSwitchCaseSelectors = 16383; bool IsValidStorageTextureDimension(type::TextureDimension dim) { switch (dim) { @@ -2315,6 +2316,13 @@ bool Validator::Return(const ast::ReturnStatement* ret, } bool Validator::SwitchStatement(const ast::SwitchStatement* s) { + if (s->body.Length() > kMaxSwitchCaseSelectors) { + AddError("switch statement has " + std::to_string(s->body.Length()) + + " case selectors, max is " + std::to_string(kMaxSwitchCaseSelectors), + s->source); + return false; + } + auto* cond_ty = sem_.TypeOf(s->condition); if (!cond_ty->is_integer_scalar()) { AddError("switch statement selector expression must be of a scalar integer type",