diff --git a/src/dawn/native/Commands.cpp b/src/dawn/native/Commands.cpp index 2e538b1476d..4a521ccde36 100644 --- a/src/dawn/native/Commands.cpp +++ b/src/dawn/native/Commands.cpp @@ -437,6 +437,13 @@ void SkipCommand(CommandIterator* commands, Command type) { const char* AddNullTerminatedString(CommandAllocator* allocator, StringView s, uint32_t* length) { std::string_view view = s; + // Bandaid: |length| is stored as uint32_t and every consumer reads back the + // string with NextData(length + 1) using uint32 arithmetic. A length of + // exactly UINT32_MAX makes (length + 1) wrap to 0 and desyncs the + // CommandIterator cursor; lengths > UINT32_MAX are silently truncated by the + // cast below with the same effect. Either path lets backend execution loops + // reach `default: DAWN_UNREACHABLE()` (== __builtin_unreachable in release). + DAWN_CHECK(view.length() < std::numeric_limits::max()); *length = static_cast(view.length()); // Include extra null-terminator character. The string_view may not be null-terminated. It also