Fixes timeout with 686/clusterfuzz-testcase-5853946876788736 this shortcuts (i.e. speeds up) the error and return-to-user when decoding a truncated frame
Showing the changes to libavcodec (2 of 2 files). Show all
Unified · Split
| @@ -2275,7 +2275,7 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, · 2274 unmodified lines | |||
| 2275 | #define update_pos(td, mb_y, mb_x) while(0) | 2275 | #define update_pos(td, mb_y, mb_x) while(0) |
| 2276 | #endif | 2276 | #endif |
| 2277 | 2277 | ||
| 2278 | static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, | 2278 | static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, |
| 2279 | int jobnr, int threadnr, int is_vp7) | 2279 | int jobnr, int threadnr, int is_vp7) |
| 2280 | { | 2280 | { |
| 2281 | VP8Context *s = avctx->priv_data; | 2281 | VP8Context *s = avctx->priv_data; |
| @@ -2291,6 +2291,10 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void · 9 unmodified lines | |||
| 2291 | curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize, | 2291 | curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize, |
| 2292 | curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize | 2292 | curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize |
| 2293 | }; | 2293 | }; |
| 2294 | |||
| 2295 | if (c->end <= c->buffer && c->bits >= 0) | ||
| 2296 | return AVERROR_INVALIDDATA; | ||
| 2297 | |||
| 2294 | if (mb_y == 0) | 2298 | if (mb_y == 0) |
| 2295 | prev_td = td; | 2299 | prev_td = td; |
| 2296 | else | 2300 | else |
| @@ -2394,18 +2398,19 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void · 97 unmodified lines | |||
| 2394 | update_pos(td, mb_y, mb_x); | 2398 | update_pos(td, mb_y, mb_x); |
| 2395 | } | 2399 | } |
| 2396 | } | 2400 | } |
| 2401 | return 0; | ||
| 2397 | } | 2402 | } |
| 2398 | 2403 | ||
| 2399 | static void vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, | 2404 | static int vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, |
| 2400 | int jobnr, int threadnr) | 2405 | int jobnr, int threadnr) |
| 2401 | { | 2406 | { |
| 2402 | decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1); | 2407 | return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1); |
| 2403 | } | 2408 | } |
| 2404 | 2409 | ||
| 2405 | static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, | 2410 | static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, |
| 2406 | int jobnr, int threadnr) | 2411 | int jobnr, int threadnr) |
| 2407 | { | 2412 | { |
| 2408 | decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0); | 2413 | return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0); |
| 2409 | } | 2414 | } |
| 2410 | 2415 | ||
| 2411 | static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, | 2416 | static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, |
| @@ -2488,13 +2493,16 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, · 76 unmodified lines | |||
| 2488 | VP8ThreadData *next_td = NULL, *prev_td = NULL; | 2493 | VP8ThreadData *next_td = NULL, *prev_td = NULL; |
| 2489 | VP8Frame *curframe = s->curframe; | 2494 | VP8Frame *curframe = s->curframe; |
| 2490 | int mb_y, num_jobs = s->num_jobs; | 2495 | int mb_y, num_jobs = s->num_jobs; |
| 2496 | int ret; | ||
| 2491 | 2497 | ||
| 2492 | td->thread_nr = threadnr; | 2498 | td->thread_nr = threadnr; |
| 2493 | for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) { | 2499 | for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) { |
| 2494 | if (mb_y >= s->mb_height) | 2500 | if (mb_y >= s->mb_height) |
| 2495 | break; | 2501 | break; |
| 2496 | td->thread_mb_pos = mb_y << 16; | 2502 | td->thread_mb_pos = mb_y << 16; |
| 2497 | s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr); | 2503 | ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr); |
| 2504 | if (ret < 0) | ||
| 2505 | return ret; | ||
| 2498 | if (s->deblock_filter) | 2506 | if (s->deblock_filter) |
| 2499 | s->filter_mb_row(avctx, tdata, jobnr, threadnr); | 2507 | s->filter_mb_row(avctx, tdata, jobnr, threadnr); |
| 2500 | update_pos(td, mb_y, INT_MAX & 0xFFFF); | 2508 | update_pos(td, mb_y, INT_MAX & 0xFFFF); |
| @@ -275,7 +275,7 @@ typedef struct VP8Context { · 274 unmodified lines | |||
| 275 | */ | 275 | */ |
| 276 | int mb_layout; | 276 | int mb_layout; |
| 277 | 277 | ||
| 278 | void (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); | 278 | int (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); |
| 279 | void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); | 279 | void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); |
| 280 | 280 | ||
| 281 | int vp7; | 281 | int vp7; |