History

Merge "vp9: Fix potential SEGV in decoder_peek_si_internal"

Vignesh Venkatasubramanian committed 10 years ago

Commit 692fe742 parents bdeb5fe aa1c8132 files · +48 −5Browse files

Unified · Split

2 files
  1. test/decode_api_test.cc +34 −0
  2. vp9/vp9_dx_iface.c +14 −5
test/decode_api_test.cc+34−0
@@ -143,6 +143,40 @@ TEST(DecodeAPI, Vp9InvalidDecode) { · 142 unmodified lines
143143 TestVp9Controls(&dec);
144144 EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
145145 }
146+
147+TEST(DecodeAPI, Vp9PeekSI) {
148+ const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
149+ // The first 9 bytes are valid and the rest of the bytes are made up. Until
150+ // size 10, this should return VPX_CODEC_UNSUP_BITSTREAM and after that it
151+ // should return VPX_CODEC_CORRUPT_FRAME.
152+ const uint8_t data[32] = {
153+ 0x85, 0xa4, 0xc1, 0xa1, 0x38, 0x81, 0xa3, 0x49,
154+ 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
155+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
156+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
157+ };
158+
159+ for (uint32_t data_sz = 1; data_sz <= 32; ++data_sz) {
160+ // Verify behavior of vpx_codec_decode. vpx_codec_decode doesn't even get
161+ // to decoder_peek_si_internal on frames of size < 8.
162+ if (data_sz >= 8) {
163+ vpx_codec_ctx_t dec;
164+ EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
165+ EXPECT_EQ((data_sz < 10) ?
166+ VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_CORRUPT_FRAME,
167+ vpx_codec_decode(&dec, data, data_sz, NULL, 0));
168+ vpx_codec_iter_t iter = NULL;
169+ EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
170+ EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
171+ }
172+
173+ // Verify behavior of vpx_codec_peek_stream_info.
174+ vpx_codec_stream_info_t si;
175+ si.sz = sizeof(si);
176+ EXPECT_EQ((data_sz < 10) ? VPX_CODEC_UNSUP_BITSTREAM : VPX_CODEC_OK,
177+ vpx_codec_peek_stream_info(codec, data, data_sz, &si));
178+ }
179+}
146180 #endif // CONFIG_VP9_DECODER
147181
148182 } // namespace
vp9/vp9_dx_iface.c+14−5
@@ -127,7 +127,7 @@ static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, · 126 unmodified lines
127127 vpx_decrypt_cb decrypt_cb,
128128 void *decrypt_state) {
129129 int intra_only_flag = 0;
130− uint8_t clear_buffer[9];
130+ uint8_t clear_buffer[10];
131131
132132 if (data + data_sz <= data)
133133 return VPX_CODEC_INVALID_PARAM;
@@ -141,6 +141,11 @@ static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, · 7 unmodified lines
141141 data = clear_buffer;
142142 }
143143
144+ // A maximum of 6 bits are needed to read the frame marker, profile and
145+ // show_existing_frame.
146+ if (data_sz < 1)
147+ return VPX_CODEC_UNSUP_BITSTREAM;
148+
144149 {
145150 int show_frame;
146151 int error_resilient;
@@ -154,15 +159,19 @@ static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, · 7 unmodified lines
154159 if (profile >= MAX_PROFILES)
155160 return VPX_CODEC_UNSUP_BITSTREAM;
156161
157− if ((profile >= 2 && data_sz <= 1) || data_sz < 1)
158− return VPX_CODEC_UNSUP_BITSTREAM;
159−
160162 if (vpx_rb_read_bit(&rb)) { // show an existing frame
163+ // If profile is > 2 and show_existing_frame is true, then at least 1 more
164+ // byte (6+3=9 bits) is needed.
165+ if (profile > 2 && data_sz < 2)
166+ return VPX_CODEC_UNSUP_BITSTREAM;
161167 vpx_rb_read_literal(&rb, 3); // Frame buffer to show.
162168 return VPX_CODEC_OK;
163169 }
164170
165− if (data_sz <= 8)
171+ // For the rest of the function, a maximum of 9 more bytes are needed
172+ // (computed by taking the maximum possible bits needed in each case). Note
173+ // that this has to be updated if we read any more bits in this function.
174+ if (data_sz < 10)
166175 return VPX_CODEC_UNSUP_BITSTREAM;
167176
168177 si->is_kf = !vpx_rb_read_bit(&rb);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t