mirror of https://git.ffmpeg.org/ffmpeg.git
avcodec/vp568: Check that there is enough data for ff_vp56_init_range_decoder()
Fixes: timeout in 730/clusterfuzz-testcase-5265113739165696 (part 1 of 2) Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg Reviewed-by: BBB Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
5098a6f627
commit
55d7371fe0
|
@ -38,8 +38,11 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
|
||||||
{
|
{
|
||||||
VP56RangeCoder *c = &s->c;
|
VP56RangeCoder *c = &s->c;
|
||||||
int rows, cols;
|
int rows, cols;
|
||||||
|
int ret;
|
||||||
|
|
||||||
ff_vp56_init_range_decoder(&s->c, buf, buf_size);
|
ret = ff_vp56_init_range_decoder(&s->c, buf, buf_size);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
s->frames[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c);
|
s->frames[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c);
|
||||||
vp56_rac_get(c);
|
vp56_rac_get(c);
|
||||||
ff_vp56_init_dequant(s, vp56_rac_gets(c, 6));
|
ff_vp56_init_dequant(s, vp56_rac_gets(c, 6));
|
||||||
|
|
|
@ -224,7 +224,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern const uint8_t ff_vp56_norm_shift[256];
|
extern const uint8_t ff_vp56_norm_shift[256];
|
||||||
void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size);
|
int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size);
|
||||||
|
|
||||||
static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c)
|
static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,11 +37,14 @@ const uint8_t ff_vp56_norm_shift[256]= {
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
};
|
};
|
||||||
|
|
||||||
void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size)
|
int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size)
|
||||||
{
|
{
|
||||||
c->high = 255;
|
c->high = 255;
|
||||||
c->bits = -16;
|
c->bits = -16;
|
||||||
c->buffer = buf;
|
c->buffer = buf;
|
||||||
c->end = buf + buf_size;
|
c->end = buf + buf_size;
|
||||||
|
if (buf_size < 1)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
c->code_word = bytestream_get_be24(&c->buffer);
|
c->code_word = bytestream_get_be24(&c->buffer);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
|
||||||
int sub_version;
|
int sub_version;
|
||||||
int rows, cols;
|
int rows, cols;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
int ret;
|
||||||
int separated_coeff = buf[0] & 1;
|
int separated_coeff = buf[0] & 1;
|
||||||
|
|
||||||
s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
|
s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
|
||||||
|
@ -93,7 +94,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
|
||||||
s->avctx->coded_width = 16 * cols;
|
s->avctx->coded_width = 16 * cols;
|
||||||
s->avctx->coded_height = 16 * rows;
|
s->avctx->coded_height = 16 * rows;
|
||||||
} else {
|
} else {
|
||||||
int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
|
ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -105,7 +106,9 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
|
||||||
res = VP56_SIZE_CHANGE;
|
res = VP56_SIZE_CHANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ff_vp56_init_range_decoder(c, buf+6, buf_size-6);
|
ret = ff_vp56_init_range_decoder(c, buf+6, buf_size-6);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
vp56_rac_gets(c, 2);
|
vp56_rac_gets(c, 2);
|
||||||
|
|
||||||
parse_filter_info = s->filter_header;
|
parse_filter_info = s->filter_header;
|
||||||
|
@ -122,7 +125,9 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
|
||||||
buf += 2;
|
buf += 2;
|
||||||
buf_size -= 2;
|
buf_size -= 2;
|
||||||
}
|
}
|
||||||
ff_vp56_init_range_decoder(c, buf+1, buf_size-1);
|
ret = ff_vp56_init_range_decoder(c, buf+1, buf_size-1);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
s->golden_frame = vp56_rac_get(c);
|
s->golden_frame = vp56_rac_get(c);
|
||||||
if (s->filter_header) {
|
if (s->filter_header) {
|
||||||
|
@ -165,7 +170,9 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
|
||||||
s->parse_coeff = vp6_parse_coeff_huffman;
|
s->parse_coeff = vp6_parse_coeff_huffman;
|
||||||
init_get_bits(&s->gb, buf, buf_size<<3);
|
init_get_bits(&s->gb, buf, buf_size<<3);
|
||||||
} else {
|
} else {
|
||||||
ff_vp56_init_range_decoder(&s->cc, buf, buf_size);
|
ret = ff_vp56_init_range_decoder(&s->cc, buf, buf_size);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
s->ccp = &s->cc;
|
s->ccp = &s->cc;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -261,6 +261,7 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
|
||||||
{
|
{
|
||||||
const uint8_t *sizes = buf;
|
const uint8_t *sizes = buf;
|
||||||
int i;
|
int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2);
|
s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2);
|
||||||
|
|
||||||
|
@ -274,13 +275,13 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
|
||||||
if (buf_size - size < 0)
|
if (buf_size - size < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size);
|
ret = ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
buf += size;
|
buf += size;
|
||||||
buf_size -= size;
|
buf_size -= size;
|
||||||
}
|
}
|
||||||
ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
|
return ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vp7_get_quants(VP8Context *s)
|
static void vp7_get_quants(VP8Context *s)
|
||||||
|
@ -518,7 +519,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si
|
||||||
|
|
||||||
memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab));
|
memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab));
|
||||||
|
|
||||||
ff_vp56_init_range_decoder(c, buf, part1_size);
|
ret = ff_vp56_init_range_decoder(c, buf, part1_size);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
buf += part1_size;
|
buf += part1_size;
|
||||||
buf_size -= part1_size;
|
buf_size -= part1_size;
|
||||||
|
|
||||||
|
@ -570,7 +573,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si
|
||||||
s->lf_delta.enabled = 0;
|
s->lf_delta.enabled = 0;
|
||||||
|
|
||||||
s->num_coeff_partitions = 1;
|
s->num_coeff_partitions = 1;
|
||||||
ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size);
|
ret = ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (!s->macroblocks_base || /* first frame */
|
if (!s->macroblocks_base || /* first frame */
|
||||||
width != s->avctx->width || height != s->avctx->height ||
|
width != s->avctx->width || height != s->avctx->height ||
|
||||||
|
@ -699,7 +704,9 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si
|
||||||
memset(&s->lf_delta, 0, sizeof(s->lf_delta));
|
memset(&s->lf_delta, 0, sizeof(s->lf_delta));
|
||||||
}
|
}
|
||||||
|
|
||||||
ff_vp56_init_range_decoder(c, buf, header_size);
|
ret = ff_vp56_init_range_decoder(c, buf, header_size);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
buf += header_size;
|
buf += header_size;
|
||||||
buf_size -= header_size;
|
buf_size -= header_size;
|
||||||
|
|
||||||
|
|
|
@ -852,7 +852,10 @@ static int decode_frame_header(AVCodecContext *ctx,
|
||||||
av_log(ctx, AV_LOG_ERROR, "Invalid compressed header size\n");
|
av_log(ctx, AV_LOG_ERROR, "Invalid compressed header size\n");
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
ff_vp56_init_range_decoder(&s->c, data2, size2);
|
res = ff_vp56_init_range_decoder(&s->c, data2, size2);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit
|
if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit
|
||||||
av_log(ctx, AV_LOG_ERROR, "Marker bit was set\n");
|
av_log(ctx, AV_LOG_ERROR, "Marker bit was set\n");
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
@ -4153,7 +4156,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
|
ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
|
res = ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit
|
if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit
|
||||||
ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
|
ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
Loading…
Reference in New Issue