Commit 120b38b9 authored by Michael Niedermayer's avatar Michael Niedermayer

avio: redesign ffio_rewind_with_probe_data()

This prevents a double free

Fixes CID718285
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 54b2d317
...@@ -64,7 +64,7 @@ static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s) ...@@ -64,7 +64,7 @@ static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
* @return 0 in case of success, a negative value corresponding to an * @return 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure * AVERROR code in case of failure
*/ */
int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size); int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **buf, int buf_size);
uint64_t ffio_read_varlen(AVIOContext *bc); uint64_t ffio_read_varlen(AVIOContext *bc);
......
...@@ -726,27 +726,32 @@ static int url_resetbuf(AVIOContext *s, int flags) ...@@ -726,27 +726,32 @@ static int url_resetbuf(AVIOContext *s, int flags)
return 0; return 0;
} }
int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size) int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size)
{ {
int64_t buffer_start; int64_t buffer_start;
int buffer_size; int buffer_size;
int overlap, new_size, alloc_size; int overlap, new_size, alloc_size;
uint8_t *buf = *bufp;
if (s->write_flag) if (s->write_flag) {
av_freep(bufp);
return AVERROR(EINVAL); return AVERROR(EINVAL);
}
buffer_size = s->buf_end - s->buffer; buffer_size = s->buf_end - s->buffer;
/* the buffers must touch or overlap */ /* the buffers must touch or overlap */
if ((buffer_start = s->pos - buffer_size) > buf_size) if ((buffer_start = s->pos - buffer_size) > buf_size) {
av_freep(bufp);
return AVERROR(EINVAL); return AVERROR(EINVAL);
}
overlap = buf_size - buffer_start; overlap = buf_size - buffer_start;
new_size = buf_size + buffer_size - overlap; new_size = buf_size + buffer_size - overlap;
alloc_size = FFMAX(s->buffer_size, new_size); alloc_size = FFMAX(s->buffer_size, new_size);
if (alloc_size > buf_size) if (alloc_size > buf_size)
if (!(buf = av_realloc_f(buf, 1, alloc_size))) if (!(buf = (*bufp) = av_realloc_f(buf, 1, alloc_size)))
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
if (new_size > buf_size) { if (new_size > buf_size) {
......
...@@ -470,8 +470,7 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, ...@@ -470,8 +470,7 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
} }
/* rewind. reuse probe buffer to avoid seeking */ /* rewind. reuse probe buffer to avoid seeking */
if ((ret = ffio_rewind_with_probe_data(pb, buf, pd.buf_size)) < 0) ret = ffio_rewind_with_probe_data(pb, &buf, pd.buf_size);
av_free(buf);
return ret; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment