From a70e365313d31757bc9b75002fa46b3366d551a8 Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Tue, 8 Nov 2022 18:27:08 +0000 Subject: [PATCH] tint: fix extractBits edge case If count is highest and offset is non-zero, or vice-versa, we'd overflow the count + offset > bit-width check. This CL fixes this case. Bug: tint:1581 Bug: chromium:1381810 Change-Id: I6ee60ec1a13230fca6f4bb6407cd33bcc6730eb7 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/109162 Commit-Queue: Antonio Maiorano Reviewed-by: Ben Clayton Kokoro: Kokoro --- src/tint/resolver/const_eval.cc | 14 +++++++------- src/tint/resolver/const_eval_builtin_test.cc | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc index 65f4d25fa3..2c012a1867 100644 --- a/src/tint/resolver/const_eval.cc +++ b/src/tint/resolver/const_eval.cc @@ -1901,18 +1901,18 @@ ConstEval::Result ConstEval::extractBits(const sem::Type* ty, NumberUT in_offset = args[1]->As(); NumberUT in_count = args[2]->As(); - constexpr UT w = sizeof(UT) * 8; - if ((in_offset + in_count) > w) { - AddError("'offset + 'count' must be less than or equal to the bit width of 'e'", - source); - return utils::Failure; - } - // Cast all to unsigned UT e = static_cast(in_e); UT o = static_cast(in_offset); UT c = static_cast(in_count); + constexpr UT w = sizeof(UT) * 8; + if (o > w || c > w || (o + c) > w) { + AddError("'offset + 'count' must be less than or equal to the bit width of 'e'", + source); + return utils::Failure; + } + NumberT result; if (c == UT{0}) { // The result is 0 if c is 0 diff --git a/src/tint/resolver/const_eval_builtin_test.cc b/src/tint/resolver/const_eval_builtin_test.cc index 80e62383bd..fddca385d5 100644 --- a/src/tint/resolver/const_eval_builtin_test.cc +++ b/src/tint/resolver/const_eval_builtin_test.cc @@ -1226,6 +1226,8 @@ INSTANTIATE_TEST_SUITE_P(ExtractBits, std::make_tuple(33, 33), // std::make_tuple(34, 34), // std::make_tuple(1000, 1000), // + std::make_tuple(u32::Highest(), 1), // + std::make_tuple(1, u32::Highest()), // std::make_tuple(u32::Highest(), u32::Highest()))); std::vector Pack4x8snormCases() {