avcodec: Avoid splitting side data repeatedly

Fixes Timeout
Fixes: 508/clusterfuzz-testcase-6245747678773248

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer 2017-05-04 17:15:18 +02:00
parent 523205ce1e
commit e813df4fa3
3 changed files with 36 additions and 2 deletions

View File

@ -462,7 +462,32 @@ int av_packet_split_side_data(AVPacket *pkt){
}
return 0;
}
#endif
#if FF_API_MERGE_SD
int ff_packet_split_and_drop_side_data(AVPacket *pkt){
if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
int i;
unsigned int size;
uint8_t *p;
p = pkt->data + pkt->size - 8 - 5;
for (i=1; ; i++){
size = AV_RB32(p);
if (size>INT_MAX - 5 || p - pkt->data < size)
return 0;
if (p[4]&128)
break;
if (p - pkt->data < size + 5)
return 0;
p-= size+5;
}
pkt->size = p - pkt->data - size;
av_assert0(pkt->size >= 0);
return 1;
}
return 0;
}
#endif
uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size)

View File

@ -392,7 +392,9 @@ static int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame)
tmp = *pkt;
#if FF_API_MERGE_SD
FF_DISABLE_DEPRECATION_WARNINGS
did_split = av_packet_split_side_data(&tmp);
did_split = avci->compat_decode_partial_size ?
ff_packet_split_and_drop_side_data(&tmp) :
av_packet_split_side_data(&tmp);
if (did_split) {
ret = extract_packet_props(avctx->internal, &tmp);
@ -961,6 +963,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
AVPacket *avpkt)
{
int i, ret = 0;
AVCodecInternal *avci = avctx->internal;
if (!avpkt->data && avpkt->size) {
av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
@ -981,7 +984,9 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
AVPacket tmp = *avpkt;
#if FF_API_MERGE_SD
FF_DISABLE_DEPRECATION_WARNINGS
int did_split = av_packet_split_side_data(&tmp);
int did_split = avci->compat_decode_partial_size ?
ff_packet_split_and_drop_side_data(&tmp) :
av_packet_split_side_data(&tmp);
//apply_param_change(avctx, &tmp);
if (did_split) {

View File

@ -356,6 +356,10 @@ int ff_set_sar(AVCodecContext *avctx, AVRational sar);
int ff_side_data_update_matrix_encoding(AVFrame *frame,
enum AVMatrixEncoding matrix_encoding);
#if FF_API_MERGE_SD
int ff_packet_split_and_drop_side_data(AVPacket *pkt);
#endif
/**
* Select the (possibly hardware accelerated) pixel format.
* This is a wrapper around AVCodecContext.get_format() and should be used