tint: Prevent integer overflow in IntrinsicTable

If the WGSL provided over 255 arguments, then we'd overflow the uint8_t,
and a bad candidate could be matched.

We have validation in place to ensure that user functions are not
declared with more than 255 parameters, but no validation for number of
arguments provided.

Fixed: chromium:1323605
Change-Id: I048709e8b02bdd95d5082128a1186080c79b2fc7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/90249
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index 18350d5..e32dc78 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -1113,11 +1113,16 @@
     constexpr int kScorePerMatchedOpenType = 1;
     constexpr int kScorePerMatchedOpenNumber = 1;
 
-    auto num_parameters = overload.num_parameters;
-    auto num_arguments = static_cast<decltype(num_parameters)>(args.size());
+    uint32_t num_parameters = static_cast<uint32_t>(overload.num_parameters);
+    uint32_t num_arguments = static_cast<uint32_t>(args.size());
 
     bool overload_matched = true;
 
+    if (static_cast<uint64_t>(args.size()) >
+        static_cast<uint64_t>(std::numeric_limits<uint32_t>::max())) {
+        overload_matched = false;  // No overload has this number of arguments.
+    }
+
     if (num_parameters != num_arguments) {
         match_score += kScorePerParamArgMismatch * (std::max(num_parameters, num_arguments) -
                                                     std::min(num_parameters, num_arguments));
diff --git a/src/tint/resolver/intrinsic_table_test.cc b/src/tint/resolver/intrinsic_table_test.cc
index ab9c90c..bec7a49 100644
--- a/src/tint/resolver/intrinsic_table_test.cc
+++ b/src/tint/resolver/intrinsic_table_test.cc
@@ -14,6 +14,8 @@
 
 #include "src/tint/resolver/intrinsic_table.h"
 
+#include <utility>
+
 #include "gmock/gmock.h"
 #include "src/tint/program_builder.h"
 #include "src/tint/sem/atomic.h"
@@ -661,5 +663,13 @@
 )");
 }
 
+TEST_F(IntrinsicTableTest, Err257Arguments) {  // crbug.com/1323605
+    auto* f32 = create<sem::F32>();
+    std::vector<const sem::Type*> arg_tys(257, f32);
+    auto* result = table->Lookup(BuiltinType::kAbs, std::move(arg_tys), Source{});
+    ASSERT_EQ(result, nullptr);
+    ASSERT_THAT(Diagnostics().str(), HasSubstr("no matching call"));
+}
+
 }  // namespace
 }  // namespace tint::resolver