Prevent negative error message ranges

If an error message was reported from Tint that had a end line/position
that occurred before the start line/position then the range would have
a negative length, causing the unsigned length to underflow into a very
large value. Also, specifically, if the start line was non-zero but the
end line was zero (indicating no line, and the value ranges are
constructed with by default) the for loop that adds the line offsets
would underflow and cause it to read off the end of the line list.

Clamping the end of the range to always be less than or equal to the
start of the range avoids both of these problems.

Bug: dawn:1245
Change-Id: I780a1f5acc228297cbbea86f33679d00e9153b4c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/75260
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: Brandon Jones <bajones@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/CompilationMessages.cpp b/src/dawn_native/CompilationMessages.cpp
index 70aae54..cc0790e 100644
--- a/src/dawn_native/CompilationMessages.cpp
+++ b/src/dawn_native/CompilationMessages.cpp
@@ -80,6 +80,16 @@
             // lines in between to the ending offset.
             uint64_t endLineNum = diagnostic.source.range.end.line;
             uint64_t endLinePos = diagnostic.source.range.end.column;
+
+            // If the range has a valid start but the end it not specified, clamp it to the start.
+            if (endLineNum == 0 || endLinePos == 0) {
+                endLineNum = lineNum;
+                endLinePos = linePos;
+            }
+
+            // Negative ranges aren't allowed
+            ASSERT(endLineNum >= lineNum);
+
             uint64_t endOffset = offset;
             for (; i < endLineNum - 1; ++i) {
                 endOffset += lines[i].length() + 1;
@@ -90,6 +100,9 @@
             offset += linePos - 1;
             endOffset += endLinePos - 1;
 
+            // Negative ranges aren't allowed
+            ASSERT(endOffset >= offset);
+
             // The length of the message is the difference between the starting offset and the
             // ending offset.
             length = endOffset - offset;