[amlogic-decoder][vp9] Limit video size

These sizes are taken directly from the bitstream, so limit them so we
won't try to create gigantic textures with invalid inputs.

Bug: 41492

Change-Id: Ifffe43fb3fb9254228db35f1a130813bf9453e2e
diff --git a/garnet/drivers/video/amlogic-decoder/tests/integration/test_vp9.cc b/garnet/drivers/video/amlogic-decoder/tests/integration/test_vp9.cc
index 03784a98..02b6e2a 100644
--- a/garnet/drivers/video/amlogic-decoder/tests/integration/test_vp9.cc
+++ b/garnet/drivers/video/amlogic-decoder/tests/integration/test_vp9.cc
@@ -581,8 +581,8 @@
     video.reset();
   }
 
-  static void DecodeMalformed(const char* input_filename, uint32_t modification_offset,
-                              uint8_t modification_value) {
+  static void DecodeMalformed(const char* input_filename,
+                              const std::vector<std::pair<uint32_t, uint8_t>>& modifications) {
     auto video = std::make_unique<AmlogicVideo>();
     ASSERT_TRUE(video);
 
@@ -631,7 +631,9 @@
     auto aml_data = ConvertIvfToAmlV(test_ivf->ptr, test_ivf->size);
     // Arbitrary modifications to an AMLV header shouldn't happen in production code,
     // because the driver is what creates that. The rest is fair game, though.
-    aml_data[modification_offset] = modification_value;
+    for (auto& mod : modifications) {
+      aml_data[mod.first] = mod.second;
+    }
     EXPECT_EQ(ZX_OK, video->parser()->ParseVideo(aml_data.data(), aml_data.size()));
     EXPECT_EQ(std::future_status::ready,
               first_wait_valid.get_future().wait_for(std::chrono::seconds(1)));
@@ -694,5 +696,17 @@
 TEST(VP9, DecodeMalformedHang) {
   // Numbers are essentially random, but picked to ensure the decoder would
   // normally hang. The offset should be >= 16 to avoid hitting the AMLV header.
-  TestVP9::DecodeMalformed("video_test_data/test-25fps.vp9", 17, 10);
+  TestVP9::DecodeMalformed("video_test_data/test-25fps.vp9", {{17, 10}});
+}
+
+TEST(VP9, DecodeMalformedLarge) {
+  constexpr uint32_t kAmlVHeaderSize = 16;
+  // Modify bits [12, 15] of the width to 0xf (and keep colorspace the same at 0x0).
+  // The width should now be 0xf13f.
+  constexpr uint32_t kWidthModificationOffset = kAmlVHeaderSize + 4;
+  // Modify bits [12, 15] of the height to 0xf (and keep the width the same, since its low 4 bits
+  // are already 0xf). The height should now be 0xf0ef.
+  constexpr uint32_t kHeightModificationOffset = kAmlVHeaderSize + 6;
+  TestVP9::DecodeMalformed("video_test_data/test-25fps.vp9",
+                           {{kWidthModificationOffset, 0x0f}, {kHeightModificationOffset, 0xff}});
 }
diff --git a/garnet/drivers/video/amlogic-decoder/vp9_decoder.cc b/garnet/drivers/video/amlogic-decoder/vp9_decoder.cc
index 2351535..d783bd0 100644
--- a/garnet/drivers/video/amlogic-decoder/vp9_decoder.cc
+++ b/garnet/drivers/video/amlogic-decoder/vp9_decoder.cc
@@ -1100,6 +1100,14 @@
   uint32_t coded_height = fbl::round_up(params->hw_height, 2u);
   uint32_t stride = fbl::round_up(params->hw_width, 32u);
 
+  // Support up to 4kx2k, the hardware limit.
+  constexpr uint32_t kMaxWidth = 4096, kMaxHeight = 2176;
+  if (coded_width > kMaxWidth || coded_height > kMaxHeight) {
+    DECODE_ERROR("Invalid stream size %dx%d\n", coded_width, coded_height);
+    CallErrorHandler();
+    return false;
+  }
+
   // If !is_current_output_buffer_collection_usable_, then we don't support dynamic dimensions.
   bool buffers_allocated = !!frames_[0]->frame || !!frames_[0]->on_deck_frame;
   // For VP9 we have kMinFrames and kMaxFrames as the min/max bounds on # of frames the decoder is