From 0f42d1fa8569532b5bed322bd1662e3d06161544 Mon Sep 17 00:00:00 2001 From: James Zern Date: Tue, 23 Aug 2016 15:51:32 -0700 Subject: [PATCH] vp8: fix decoder crash with invalid leading keyframes decoding the same invalid keyframe twice would result in a crash as the second time through the decoder would be assumed to have been initialized as there was no resolution change. in this case the resolution was itself invalid (0x6), but vp8_peek_si() was only failing in the case of 0x0. invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf tests this case by duplicating the first keyframe and additionally adds a valid one to ensure decoding can resume without error. BUG=b/30593765 Change-Id: If0859035908b7870d67a7f3f646b5a080252eb6d --- test/invalid_file_test.cc | 9 +++++++++ test/test-data.mk | 2 ++ test/test-data.sha1 | 6 ++++-- test/test.mk | 6 +++++- vp8/vp8_dx_iface.c | 6 +++++- 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/test/invalid_file_test.cc b/test/invalid_file_test.cc index f3ac4a7..9c477fd 100644 --- a/test/invalid_file_test.cc +++ b/test/invalid_file_test.cc @@ -158,6 +158,13 @@ class InvalidFileInvalidPeekTest : public InvalidFileTest { TEST_P(InvalidFileInvalidPeekTest, ReturnCode) { RunTest(); } +const DecodeParam kVP8InvalidFileTests[] = { + { 1, "invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf" }, +}; + +VP8_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest, + ::testing::ValuesIn(kVP8InvalidFileTests)); + const DecodeParam kVP9InvalidFileInvalidPeekTests[] = { { 1, "invalid-vp90-01-v3.webm" }, }; @@ -165,6 +172,7 @@ const DecodeParam kVP9InvalidFileInvalidPeekTests[] = { VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest, ::testing::ValuesIn(kVP9InvalidFileInvalidPeekTests)); +#if CONFIG_VP9_DECODER const DecodeParam kMultiThreadedVP9InvalidFileTests[] = { { 4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm" }, { 4, @@ -182,4 +190,5 @@ INSTANTIATE_TEST_CASE_P( ::testing::Values( static_cast(&libvpx_test::kVP9)), ::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests))); +#endif // CONFIG_VP9_DECODER } // namespace diff --git a/test/test-data.mk b/test/test-data.mk index 80af6e3..da2fd77 100644 --- a/test/test-data.mk +++ b/test/test-data.mk @@ -730,6 +730,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv444.webm.md5 endif # CONFIG_VP9_HIGHBITDEPTH # Invalid files for testing libvpx error checking. +LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf +LIBVPX_TEST_DATA-$(CONFIG_VP8_DECODER) += invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm diff --git a/test/test-data.sha1 b/test/test-data.sha1 index 18a8773..7dd4fcf 100644 --- a/test/test-data.sha1 +++ b/test/test-data.sha1 @@ -834,5 +834,7 @@ f6856f19236ee46ed462bd0a2e7e72b9c3b9cea6 *vp90-2-21-resize_inter_640x480_5_1-2.w 7739bfca167b1b43fea72f807f01e097b7cb98d8 *vp90-2-21-resize_inter_640x480_7_1-2.webm.md5 7291af354b4418917eee00e3a7e366086a0b7a10 *vp90-2-21-resize_inter_640x480_7_3-4.webm 4a18b09ccb36564193f0215f599d745d95bb558c *vp90-2-21-resize_inter_640x480_7_3-4.webm.md5 -a000d568431d07379dd5a8ec066061c07e560b47 invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf -1e75aad3433c5c21c194a7b53fc393970f0a8d7f invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf.res +a000d568431d07379dd5a8ec066061c07e560b47 *invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf +1e75aad3433c5c21c194a7b53fc393970f0a8d7f *invalid-vp90-2-00-quantizer-63.ivf.kf_65527x61446.ivf.res +235182f9a1c5c8841552510dd4288487447bfc40 *invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf +787f04f0483320d536894282f3358a4f8cac1cf9 *invalid-vp80-00-comprehensive-018.ivf.2kf_0x6.ivf.res diff --git a/test/test.mk b/test/test.mk index 81381e9..8b1e597 100644 --- a/test/test.mk +++ b/test/test.mk @@ -35,7 +35,6 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += keyframe_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += byte_alignment_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += external_frame_buffer_test.cc -LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += invalid_file_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += user_priv_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_frame_parallel_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_refresh_test.cc @@ -88,6 +87,11 @@ ifeq ($(CONFIG_ENCODE_PERF_TESTS)$(CONFIG_VP9_ENCODER), yesyes) LIBVPX_TEST_SRCS-yes += encode_perf_test.cc endif +## Multi-codec blackbox tests. +ifeq ($(findstring yes,$(CONFIG_VP8_DECODER)$(CONFIG_VP9_DECODER)), yes) +LIBVPX_TEST_SRCS-yes += invalid_file_test.cc +endif + ## ## WHITE BOX TESTS ## diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index 61c8484..674a856 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -177,7 +177,7 @@ static vpx_codec_err_t vp8_peek_si_internal(const uint8_t *data, si->h = (clear[8] | (clear[9] << 8)) & 0x3fff; /*printf("w=%d, h=%d\n", si->w, si->h);*/ - if (!(si->h | si->w)) res = VPX_CODEC_UNSUP_BITSTREAM; + if (!(si->h && si->w)) res = VPX_CODEC_CORRUPT_FRAME; } else { res = VPX_CODEC_UNSUP_BITSTREAM; } @@ -368,6 +368,10 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx, if (setjmp(pbi->common.error.jmp)) { pbi->common.error.setjmp = 0; + /* on failure clear the cached resolution to ensure a full + * reallocation is attempted on resync. */ + ctx->si.w = 0; + ctx->si.h = 0; vp8_clear_system_state(); /* same return value as used in vp8dx_receive_compressed_data */ return -1; -- 2.7.4