shithub: libvpx

Download patch

ref: 0f42d1fa8569532b5bed322bd1662e3d06161544
parent: f6c5410cd407a0e956edef406826baa3719b8cb2
author: James Zern <jzern@google.com>
date: Tue Aug 23 11:51:32 EDT 2016

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

--- a/test/invalid_file_test.cc
+++ b/test/invalid_file_test.cc
@@ -158,6 +158,13 @@
 
 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 @@
 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 @@
         ::testing::Values(
             static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
         ::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests)));
+#endif  // CONFIG_VP9_DECODER
 }  // namespace
--- a/test/test-data.mk
+++ b/test/test-data.mk
@@ -730,6 +730,8 @@
 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
--- a/test/test-data.sha1
+++ b/test/test-data.sha1
@@ -834,5 +834,7 @@
 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
--- a/test/test.mk
+++ b/test/test.mk
@@ -35,7 +35,6 @@
 
 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
@@ -86,6 +85,11 @@
 # encode perf tests are vp9 only
 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
 
 ##
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -177,7 +177,7 @@
       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 @@
 
         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;