vp8: Validate dimensions when setting reference frame Modifty the vp8_set/get_reference to validate the dimensions of the references match the dimensions of the internal reference buffer. Add unittest. Bug: 526737981 Change-Id: I81c3ff470fce3f25c6e30c605ddf2a925d682f6a
diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc index 21bc2e8..809ea8a 100644 --- a/test/encode_api_test.cc +++ b/test/encode_api_test.cc
@@ -532,6 +532,44 @@ vpx_codec_destroy(&enc); } +// Bug: 526737981. +TEST(EncodeAPI, SetReferenceSizeValidationVp8) { + vpx_codec_iface_t *const iface = vpx_codec_vp8_cx(); + vpx_codec_enc_cfg_t cfg; + vpx_codec_ctx_t enc; + ASSERT_EQ(vpx_codec_enc_config_default(iface, &cfg, 0), VPX_CODEC_OK); + + cfg.g_w = 128; + cfg.g_h = 128; + + ASSERT_EQ(vpx_codec_enc_init(&enc, iface, &cfg, 0), VPX_CODEC_OK); + + vpx_image_t raw; + ASSERT_NE(vpx_img_alloc(&raw, VPX_IMG_FMT_I420, 128, 128, 1), nullptr); + ASSERT_EQ(vpx_codec_encode(&enc, &raw, 0, 1, 0, VPX_DL_REALTIME), + VPX_CODEC_OK); + + // Create a larger reference frame. + vpx_image_t ref_img; + ASSERT_NE(vpx_img_alloc(&ref_img, VPX_IMG_FMT_I420, 256, 256, 1), nullptr); + + vpx_ref_frame_t ref_frame; + ref_frame.frame_type = VP8_LAST_FRAME; + ref_frame.img = ref_img; + + // Setting the reference frame with incorrect size must fail. + EXPECT_EQ(vpx_codec_control(&enc, VP8_SET_REFERENCE, &ref_frame), + VPX_CODEC_INVALID_PARAM); + + // Copying reference frame with incorrect size must also fail. + EXPECT_EQ(vpx_codec_control(&enc, VP8_COPY_REFERENCE, &ref_frame), + VPX_CODEC_INVALID_PARAM); + + vpx_img_free(&raw); + vpx_img_free(&ref_img); + EXPECT_EQ(vpx_codec_destroy(&enc), VPX_CODEC_OK); +} + // Emulates the WebCodecs VideoEncoder interface. class VP8Encoder { public:
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index d64b870..e3a4286 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c
@@ -2441,6 +2441,11 @@ return -1; } + if (cm->yv12_fb[ref_fb_idx].y_width != sd->y_width || + cm->yv12_fb[ref_fb_idx].y_height != sd->y_height) { + return -1; + } + vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd); return 0; @@ -2461,6 +2466,11 @@ return -1; } + if (cm->yv12_fb[ref_fb_idx].y_width != sd->y_width || + cm->yv12_fb[ref_fb_idx].y_height != sd->y_height) { + return -1; + } + vp8_yv12_copy_frame(sd, &cm->yv12_fb[ref_fb_idx]); return 0;
diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index e4f3c676..314f733 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c
@@ -1178,7 +1178,9 @@ YV12_BUFFER_CONFIG sd; image2yuvconfig(&frame->img, &sd); - vp8_set_reference(ctx->cpi, frame->frame_type, &sd); + if (vp8_set_reference(ctx->cpi, frame->frame_type, &sd)) { + return VPX_CODEC_INVALID_PARAM; + } return VPX_CODEC_OK; } else { return VPX_CODEC_INVALID_PARAM; @@ -1194,7 +1196,9 @@ YV12_BUFFER_CONFIG sd; image2yuvconfig(&frame->img, &sd); - vp8_get_reference(ctx->cpi, frame->frame_type, &sd); + if (vp8_get_reference(ctx->cpi, frame->frame_type, &sd)) { + return VPX_CODEC_INVALID_PARAM; + } return VPX_CODEC_OK; } else { return VPX_CODEC_INVALID_PARAM;