summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Zern <jzern@google.com>2014-08-09 18:47:58 -0700
committerJames Zern <jzern@google.com>2014-08-12 17:41:47 -0700
commit7d9da93a973d53c65db8f174b2a70297a9d2a49f (patch)
tree56582e7f361ca459331400a11f103db55dbca129
parent6a2e9ef20aed3b87259e9491fc76c0b83a76ab3c (diff)
downloadlibvpx-7d9da93a973d53c65db8f174b2a70297a9d2a49f.tar
libvpx-7d9da93a973d53c65db8f174b2a70297a9d2a49f.tar.gz
libvpx-7d9da93a973d53c65db8f174b2a70297a9d2a49f.tar.bz2
libvpx-7d9da93a973d53c65db8f174b2a70297a9d2a49f.zip
VP8D_GET_FRAME_CORRUPTED: check frame pointer
if the decode of the first frame fails, frame_to_show may not be set. fixes a crash in vpxdec with corrupt data. Change-Id: I5ab9476d005778a13fd42a39d05876bb6c90a93c
-rw-r--r--test/decode_api_test.cc49
-rw-r--r--vp8/vp8_dx_iface.c5
-rw-r--r--vp9/vp9_dx_iface.c9
3 files changed, 56 insertions, 7 deletions
diff --git a/test/decode_api_test.cc b/test/decode_api_test.cc
index 86097cd2a..06790645f 100644
--- a/test/decode_api_test.cc
+++ b/test/decode_api_test.cc
@@ -9,6 +9,7 @@
*/
#include "third_party/googletest/src/include/gtest/gtest.h"
+#include "test/ivf_video_source.h"
#include "./vpx_config.h"
#include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h"
@@ -56,4 +57,52 @@ TEST(DecodeAPI, InvalidParams) {
}
}
+#if CONFIG_VP9_DECODER
+// Test VP9 codec controls after a decode error to ensure the code doesn't
+// misbehave.
+void TestVp9Controls(vpx_codec_ctx_t *dec) {
+ static const int kControls[] = {
+ VP8D_GET_LAST_REF_UPDATES,
+ VP8D_GET_FRAME_CORRUPTED,
+ VP9D_GET_DISPLAY_SIZE,
+ };
+ int val[2];
+
+ for (int i = 0; i < NELEMENTS(kControls); ++i) {
+ const vpx_codec_err_t res = vpx_codec_control_(dec, kControls[i], val);
+ switch (kControls[i]) {
+ case VP8D_GET_FRAME_CORRUPTED:
+ EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
+ break;
+ default:
+ EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i];
+ break;
+ }
+ EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
+ vpx_codec_control_(dec, kControls[i], NULL));
+ }
+}
+
+TEST(DecodeAPI, Vp9InvalidDecode) {
+ const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
+ const char filename[] =
+ "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf";
+ libvpx_test::IVFVideoSource video(filename);
+ video.Init();
+ video.Begin();
+ ASSERT_TRUE(!HasFailure());
+
+ vpx_codec_ctx_t dec;
+ EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
+ EXPECT_EQ(VPX_CODEC_MEM_ERROR,
+ vpx_codec_decode(&dec, video.cxdata(), video.frame_size(), NULL,
+ 0));
+ vpx_codec_iter_t iter = NULL;
+ EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
+
+ TestVp9Controls(&dec);
+ EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
+}
+#endif // CONFIG_VP9_DECODER
+
} // namespace
diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c
index 0fe0c921f..9a0cdb79a 100644
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -746,8 +746,9 @@ static vpx_codec_err_t vp8_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
if (corrupted && pbi)
{
- *corrupted = pbi->common.frame_to_show->corrupted;
-
+ const YV12_BUFFER_CONFIG *const frame = pbi->common.frame_to_show;
+ if (frame == NULL) return VPX_CODEC_ERROR;
+ *corrupted = frame->corrupted;
return VPX_CODEC_OK;
}
else
diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c
index bc7801152..4372ac9e5 100644
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -639,11 +639,10 @@ static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
va_list args) {
int *corrupted = va_arg(args, int *);
- if (corrupted) {
- if (ctx->pbi)
- *corrupted = ctx->pbi->common.frame_to_show->corrupted;
- else
- return VPX_CODEC_ERROR;
+ if (corrupted != NULL && ctx->pbi != NULL) {
+ const YV12_BUFFER_CONFIG *const frame = ctx->pbi->common.frame_to_show;
+ if (frame == NULL) return VPX_CODEC_ERROR;
+ *corrupted = frame->corrupted;
return VPX_CODEC_OK;
} else {
return VPX_CODEC_INVALID_PARAM;