WireCmd: guard against overflows when computing array sizes

BUG=chromium:918094
BUG=chromium:918348
BUG=chromium:918260

Change-Id: Ia2ee8930592e436e8d0d76837b70e726e8d87ea7
Reviewed-on: https://dawn-review.googlesource.com/c/3620
Reviewed-by: Stephen White <senorblanco@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/generator/templates/dawn_wire/WireCmd.cpp b/generator/templates/dawn_wire/WireCmd.cpp
index 2464bf0..8bb4235 100644
--- a/generator/templates/dawn_wire/WireCmd.cpp
+++ b/generator/templates/dawn_wire/WireCmd.cpp
@@ -17,6 +17,7 @@
 #include "common/Assert.h"
 
 #include <cstring>
+#include <limits>
 
 //* Helper macros so that the main [de]serialization functions can be written in a generic manner.
 
@@ -288,7 +289,11 @@
         // Returns FatalError if not enough memory was available
         template <typename T>
         DeserializeResult GetPtrFromBuffer(const char** buffer, size_t* size, size_t count, const T** data) {
-            // TODO(cwallez@chromium.org): For robustness we would need to handle overflows here.
+            constexpr size_t kMaxCountWithoutOverflows = std::numeric_limits<size_t>::max() / sizeof(T);
+            if (count > kMaxCountWithoutOverflows) {
+                return DeserializeResult::FatalError;
+            }
+
             size_t totalSize = sizeof(T) * count;
             if (totalSize > *size) {
                 return DeserializeResult::FatalError;
@@ -305,7 +310,11 @@
         // Return FatalError if the allocator couldn't allocate the memory.
         template <typename T>
         DeserializeResult GetSpace(DeserializeAllocator* allocator, size_t count, T** out) {
-            // TODO(cwallez@chromium.org): For robustness we would need to handle overflows here.
+            constexpr size_t kMaxCountWithoutOverflows = std::numeric_limits<size_t>::max() / sizeof(T);
+            if (count > kMaxCountWithoutOverflows) {
+                return DeserializeResult::FatalError;
+            }
+
             size_t totalSize = sizeof(T) * count;
             *out = static_cast<T*>(allocator->GetSpace(totalSize));
             if (*out == nullptr) {