[stream] Check for size invalidity before reserving in Stream::Read

We are seeing some crashes when trying to deserialize MslCompilation
with Graphite Dawn. This change checks for invalidity when trying to
reserve vector with size which can be larger than max_size.

Change-Id: I2e5e059c68388d4e0a83efb976275d2d475c90ab
Bug: chromium:372224129
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/229254
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/native/stream/Stream.h b/src/dawn/native/stream/Stream.h
index ab2838b..8dde2be 100644
--- a/src/dawn/native/stream/Stream.h
+++ b/src/dawn/native/stream/Stream.h
@@ -291,6 +291,8 @@
         using SizeT = decltype(std::declval<std::vector<T>>().size());
         SizeT size;
         DAWN_TRY(StreamOut(s, &size));
+        DAWN_INVALID_IF(size >= v->max_size(),
+                        "Trying to reserve a vector of size larger than max_size");
         *v = {};
         v->reserve(size);
         for (SizeT i = 0; i < size; ++i) {
diff --git a/src/dawn/tests/unittests/native/StreamTests.cpp b/src/dawn/tests/unittests/native/StreamTests.cpp
index 8df1749..c100f39 100644
--- a/src/dawn/tests/unittests/native/StreamTests.cpp
+++ b/src/dawn/tests/unittests/native/StreamTests.cpp
@@ -27,6 +27,7 @@
 
 #include <cstring>
 #include <iomanip>
+#include <limits>
 #include <string>
 #include <tuple>
 #include <unordered_map>
@@ -228,6 +229,32 @@
     EXPECT_CACHE_KEY_EQ(data, expected);
 }
 
+// Test that serializing a value, then deserializing it with unexpected size, an error is raised.
+TEST(SerializeTests, SerializeDeserializeVectorSizeOutOfBounds) {
+    size_t value = std::numeric_limits<size_t>::max();
+    ByteVectorSink sink;
+    StreamIn(&sink, value);
+
+    BlobSource source(CreateBlob(std::move(sink)));
+    std::vector<uint8_t> deserialized;
+    auto err = StreamOut(&source, &deserialized);
+    EXPECT_TRUE(err.IsError());
+    err.AcquireError();
+}
+
+// Test that serializing a value, then deserializing it without vector elements, an error is raised.
+TEST(SerializeTests, SerializeDeserializeNoElementsInVector) {
+    size_t value = 1;
+    ByteVectorSink sink;
+    StreamIn(&sink, value);
+
+    BlobSource source(CreateBlob(std::move(sink)));
+    std::vector<uint8_t> deserialized;
+    auto err = StreamOut(&source, &deserialized);
+    EXPECT_TRUE(err.IsError());
+    err.AcquireError();
+}
+
 // Test that ByteVectorSink serializes std::pair as expected.
 TEST(SerializeTests, StdPair) {
     std::string_view s = "hi!";