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 | 2275 | #define update_pos(td, mb_y, mb_x) while(0) |
| 2276 | 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 | 2279 | int jobnr, int threadnr, int is_vp7) |
| 2280 | 2280 | { |
| 2281 | 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 | 2291 | curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize, |
| 2292 | 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 | 2298 | if (mb_y == 0) |
| 2295 | 2299 | prev_td = td; |
| 2296 | 2300 | else |
| @@ -2394,18 +2398,19 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void · 97 unmodified lines | ||
| 2394 | 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 | 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 | 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 | 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 | 2493 | VP8ThreadData *next_td = NULL, *prev_td = NULL; |
| 2489 | 2494 | VP8Frame *curframe = s->curframe; |
| 2490 | 2495 | int mb_y, num_jobs = s->num_jobs; |
| 2496 | + int ret; | |
| 2491 | 2497 | |
| 2492 | 2498 | td->thread_nr = threadnr; |
| 2493 | 2499 | for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) { |
| 2494 | 2500 | if (mb_y >= s->mb_height) |
| 2495 | 2501 | break; |
| 2496 | 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 | 2506 | if (s->deblock_filter) |
| 2499 | 2507 | s->filter_mb_row(avctx, tdata, jobnr, threadnr); |
| 2500 | 2508 | update_pos(td, mb_y, INT_MAX & 0xFFFF); |
| @@ -275,7 +275,7 @@ typedef struct VP8Context { · 274 unmodified lines | ||
| 275 | 275 | */ |
| 276 | 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 | 279 | void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); |
| 280 | 280 | |
| 281 | 281 | int vp7; |