Commit bc69d5460f for aom
commit bc69d5460f555372b49ba45a44e8b9fd2939fd0c
Author: Marco Paniconi <marpan@google.com>
Date: Tue Nov 10 02:55:29 2026 +0000
Check frame dimensions in av1_is_integer_mv()
When resolution changes mid-stream on an inter frame, cur_picture
(cpi->source) and last_picture (cpi->unscaled_last_source) can have
different dimensions. Return 0 in av1_is_integer_mv() if their
dimensions do not match to avoid reading past the bounds of
last_picture->y_buffer.
Added unittest EncodeAPI.Buganizer580372713.
Bug: 580372713
Change-Id: I851e01d420db20ff7e94711fb66661c1614121d2
diff --git a/av1/encoder/encoder_utils.c b/av1/encoder/encoder_utils.c
index d45d4eb039..3d995baca6 100644
--- a/av1/encoder/encoder_utils.c
+++ b/av1/encoder/encoder_utils.c
@@ -1400,6 +1400,10 @@ int av1_is_integer_mv(const YV12_BUFFER_CONFIG *cur_picture,
const int pic_width = cur_picture->y_width;
const int pic_height = cur_picture->y_height;
+ if (pic_width != last_picture->y_width ||
+ pic_height != last_picture->y_height) {
+ return 0;
+ }
for (int i = 0; i + block_size <= pic_height; i += block_size) {
for (int j = 0; j + block_size <= pic_width; j += block_size) {
const int x_pos = j;
diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc
index 8332b14072..83c493333e 100644
--- a/test/encode_api_test.cc
+++ b/test/encode_api_test.cc
@@ -3741,6 +3741,52 @@ TEST(EncodeAPI, Buganizer565488030) {
}
}
}
+
+// Regression test for b/580372713: Heap-buffer-overflow in av1_is_integer_mv()
+// when resolution increases mid-stream on an inter frame with screen content
+// tools enabled.
+TEST(EncodeAPI, Buganizer580372713) {
+ aom_codec_iface_t *const iface = aom_codec_av1_cx();
+ aom_codec_enc_cfg_t cfg;
+ ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY),
+ AOM_CODEC_OK);
+
+ cfg.g_w = 64;
+ cfg.g_h = 64;
+ cfg.g_forced_max_frame_width = 800;
+ cfg.g_forced_max_frame_height = 800;
+ cfg.g_pass = AOM_RC_ONE_PASS;
+ cfg.g_lag_in_frames = 0;
+ cfg.g_threads = 1;
+
+ aom_codec_ctx_t enc;
+ ASSERT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 6), AOM_CODEC_OK);
+ ASSERT_EQ(aom_codec_control(&enc, AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN),
+ AOM_CODEC_OK);
+
+ aom_image_t *img_small = aom_img_alloc(nullptr, AOM_IMG_FMT_I420, 64, 64, 1);
+ ASSERT_NE(img_small, nullptr);
+ FillImage(img_small, 128);
+
+ aom_image_t *img_large = aom_img_alloc(nullptr, AOM_IMG_FMT_I420, 64, 768, 1);
+ ASSERT_NE(img_large, nullptr);
+ FillImage(img_large, 128);
+
+ // Frame 0 at 64x64.
+ EncodeOne(&enc, img_small, 0);
+
+ // Increase resolution to 64x768 on an inter frame so cpi->source (64x768) is
+ // larger than cpi->unscaled_last_source (64x64).
+ cfg.g_w = 64;
+ cfg.g_h = 768;
+ ASSERT_EQ(aom_codec_enc_config_set(&enc, &cfg), AOM_CODEC_OK);
+ EncodeOne(&enc, img_large, 1);
+
+ aom_img_free(img_small);
+ aom_img_free(img_large);
+ ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
+}
#endif // !CONFIG_REALTIME_ONLY
// Regression test for b/568565869: Undefined left-shift overflow of