Fix for out-of-bounds write in square test frame generator.

The length is set on construction and includes an assumption on the
image resolution, if the resolution changes, a square might be larger
than what fits into the buffer, causing an out of bounds write. This
CL fixes this simply by restricting the size of the square.

Bug: webrtc:11415
Change-Id: Iee14a1971997b4ae2fddef0a7af7c76a2509e879
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170042
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Ali Tofigh <alito@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30732}
diff --git a/test/frame_generator.cc b/test/frame_generator.cc
index e3b4a06..1f99842 100644
--- a/test/frame_generator.cc
+++ b/test/frame_generator.cc
@@ -116,21 +116,23 @@
   RTC_DCHECK(frame_buffer->type() == VideoFrameBuffer::Type::kI420 ||
              frame_buffer->type() == VideoFrameBuffer::Type::kI420A);
   rtc::scoped_refptr<I420BufferInterface> buffer = frame_buffer->ToI420();
-  x_ = (x_ + random_generator_.Rand(0, 4)) % (buffer->width() - length_);
-  y_ = (y_ + random_generator_.Rand(0, 4)) % (buffer->height() - length_);
-  for (int y = y_; y < y_ + length_; ++y) {
+  int length_cap = std::min(buffer->height(), buffer->width()) / 4;
+  int length = std::min(length_, length_cap);
+  x_ = (x_ + random_generator_.Rand(0, 4)) % (buffer->width() - length);
+  y_ = (y_ + random_generator_.Rand(0, 4)) % (buffer->height() - length);
+  for (int y = y_; y < y_ + length; ++y) {
     uint8_t* pos_y =
         (const_cast<uint8_t*>(buffer->DataY()) + x_ + y * buffer->StrideY());
-    memset(pos_y, yuv_y_, length_);
+    memset(pos_y, yuv_y_, length);
   }
 
-  for (int y = y_; y < y_ + length_; y = y + 2) {
+  for (int y = y_; y < y_ + length; y = y + 2) {
     uint8_t* pos_u = (const_cast<uint8_t*>(buffer->DataU()) + x_ / 2 +
                       y / 2 * buffer->StrideU());
-    memset(pos_u, yuv_u_, length_ / 2);
+    memset(pos_u, yuv_u_, length / 2);
     uint8_t* pos_v = (const_cast<uint8_t*>(buffer->DataV()) + x_ / 2 +
                       y / 2 * buffer->StrideV());
-    memset(pos_v, yuv_v_, length_ / 2);
+    memset(pos_v, yuv_v_, length / 2);
   }
 
   if (frame_buffer->type() == VideoFrameBuffer::Type::kI420)
@@ -138,10 +140,10 @@
 
   // Optionally draw on alpha plane if given.
   const webrtc::I420ABufferInterface* yuva_buffer = frame_buffer->GetI420A();
-  for (int y = y_; y < y_ + length_; ++y) {
+  for (int y = y_; y < y_ + length; ++y) {
     uint8_t* pos_y = (const_cast<uint8_t*>(yuva_buffer->DataA()) + x_ +
                       y * yuva_buffer->StrideA());
-    memset(pos_y, yuv_a_, length_);
+    memset(pos_y, yuv_a_, length);
   }
 }
 
diff --git a/test/testsupport/ivf_video_frame_generator_unittest.cc b/test/testsupport/ivf_video_frame_generator_unittest.cc
index a5e99d1..0c364db 100644
--- a/test/testsupport/ivf_video_frame_generator_unittest.cc
+++ b/test/testsupport/ivf_video_frame_generator_unittest.cc
@@ -48,7 +48,7 @@
 static const VideoEncoder::Capabilities kCapabilities(false);
 
 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
-constexpr double kExpectedMinPsnr = 36;
+constexpr double kExpectedMinPsnr = 35;
 #else
 constexpr double kExpectedMinPsnr = 39;
 #endif