Merge commit '43c0a87279e717c1384314c6da7155c306ee7c60' into release/0.10
* commit '43c0a87279e717c1384314c6da7155c306ee7c60': qdm2: check that the FFT size is a power of 2 indeo3: switch parsing the header to bytestream2 indeo3: check motion vectors. rv10: check that extradata is large enough indeo3: fix data size check lavf: make sure stream probe data gets freed. dfa: check for invalid access in decode_wdlt(). xmv: check audio track parameters validity. bmv: check for len being valid in bmv_decode_frame(). xmv: do not leak memory in the error paths in xmv_read_header() avfiltergraph: check for sws opts being non-NULL before using them. oma: Validate sample rates Prepare for 0.8.7 Release Conflicts: RELEASE libavcodec/indeo3.c libavfilter/avfiltergraph.c libavformat/utils.c libavformat/xmv.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
@@ -138,7 +138,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
|
||||
mode += 1 + advance_mode;
|
||||
if (mode >= 4)
|
||||
mode -= 3;
|
||||
if (FFABS(dst_end - dst) < len)
|
||||
if (len <= 0 || FFABS(dst_end - dst) < len)
|
||||
return -1;
|
||||
switch (mode) {
|
||||
case 1:
|
||||
|
@@ -258,6 +258,8 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height
|
||||
segments = bytestream2_get_le16(gb);
|
||||
}
|
||||
line_ptr = frame;
|
||||
if (frame_end - frame < width)
|
||||
return AVERROR_INVALIDDATA;
|
||||
frame += width;
|
||||
y++;
|
||||
while (segments--) {
|
||||
|
@@ -222,7 +222,7 @@ static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
|
||||
* @param plane pointer to the plane descriptor
|
||||
* @param cell pointer to the cell descriptor
|
||||
*/
|
||||
static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
|
||||
static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
|
||||
{
|
||||
int h, w, mv_x, mv_y, offset, offset_dst;
|
||||
uint8_t *src, *dst;
|
||||
@@ -235,6 +235,16 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
|
||||
mv_x = cell->mv_ptr[1];
|
||||
}else
|
||||
mv_x= mv_y= 0;
|
||||
|
||||
/* -1 because there is an extra line on top for prediction */
|
||||
if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
|
||||
((cell->ypos + cell->height) << 2) + mv_y >= plane->height ||
|
||||
((cell->xpos + cell->width) << 2) + mv_x >= plane->width) {
|
||||
av_log(ctx->avctx, AV_LOG_ERROR,
|
||||
"Motion vectors point out of the frame.\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
offset = offset_dst + mv_y * plane->pitch + mv_x;
|
||||
src = plane->pixels[ctx->buf_sel ^ 1] + offset;
|
||||
|
||||
@@ -262,6 +272,8 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -587,11 +599,23 @@ static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
|
||||
} else if (mode >= 10) {
|
||||
/* for mode 10 and 11 INTER first copy the predicted cell into the current one */
|
||||
/* so we don't need to do data copying for each RLE code later */
|
||||
copy_cell(ctx, plane, cell);
|
||||
int ret = copy_cell(ctx, plane, cell);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
/* set the pointer to the reference pixels for modes 0-4 INTER */
|
||||
mv_y = cell->mv_ptr[0];
|
||||
mv_x = cell->mv_ptr[1];
|
||||
|
||||
/* -1 because there is an extra line on top for prediction */
|
||||
if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
|
||||
((cell->ypos + cell->height) << 2) + mv_y >= plane->height ||
|
||||
((cell->xpos + cell->width) << 2) + mv_x >= plane->width) {
|
||||
av_log(ctx->avctx, AV_LOG_ERROR,
|
||||
"Motion vectors point out of the frame.\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
offset += mv_y * plane->pitch + mv_x;
|
||||
ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset;
|
||||
}
|
||||
@@ -723,7 +747,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
|
||||
const int depth, const int strip_width)
|
||||
{
|
||||
Cell curr_cell;
|
||||
int bytes_used;
|
||||
int bytes_used, ret;
|
||||
|
||||
if (depth <= 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");
|
||||
@@ -774,8 +798,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
|
||||
CHECK_CELL
|
||||
if (!curr_cell.mv_ptr)
|
||||
return AVERROR_INVALIDDATA;
|
||||
copy_cell(ctx, plane, &curr_cell);
|
||||
return 0;
|
||||
ret = copy_cell(ctx, plane, &curr_cell);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
case INTER_DATA:
|
||||
@@ -858,17 +882,20 @@ static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
|
||||
static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
const uint8_t *buf_ptr = buf, *bs_hdr;
|
||||
GetByteContext gb;
|
||||
const uint8_t *bs_hdr;
|
||||
uint32_t frame_num, word2, check_sum, data_size;
|
||||
uint32_t y_offset, u_offset, v_offset, starts[3], ends[3];
|
||||
uint16_t height, width;
|
||||
int i, j;
|
||||
|
||||
bytestream2_init(&gb, buf, buf_size);
|
||||
|
||||
/* parse and check the OS header */
|
||||
frame_num = bytestream_get_le32(&buf_ptr);
|
||||
word2 = bytestream_get_le32(&buf_ptr);
|
||||
check_sum = bytestream_get_le32(&buf_ptr);
|
||||
data_size = bytestream_get_le32(&buf_ptr);
|
||||
frame_num = bytestream2_get_le32(&gb);
|
||||
word2 = bytestream2_get_le32(&gb);
|
||||
check_sum = bytestream2_get_le32(&gb);
|
||||
data_size = bytestream2_get_le32(&gb);
|
||||
|
||||
if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) {
|
||||
av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n");
|
||||
@@ -876,28 +903,27 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
|
||||
}
|
||||
|
||||
/* parse the bitstream header */
|
||||
bs_hdr = buf_ptr;
|
||||
bs_hdr = gb.buffer;
|
||||
|
||||
if (bytestream_get_le16(&buf_ptr) != 32) {
|
||||
if (bytestream2_get_le16(&gb) != 32) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ctx->frame_num = frame_num;
|
||||
ctx->frame_flags = bytestream_get_le16(&buf_ptr);
|
||||
ctx->data_size = (bytestream_get_le32(&buf_ptr) + 7) >> 3;
|
||||
ctx->cb_offset = *buf_ptr++;
|
||||
ctx->frame_flags = bytestream2_get_le16(&gb);
|
||||
ctx->data_size = (bytestream2_get_le32(&gb) + 7) >> 3;
|
||||
ctx->cb_offset = bytestream2_get_byte(&gb);
|
||||
|
||||
if (ctx->data_size == 16)
|
||||
return 4;
|
||||
if (ctx->data_size > buf_size)
|
||||
ctx->data_size = buf_size;
|
||||
ctx->data_size = FFMIN(ctx->data_size, buf_size - 16);
|
||||
|
||||
buf_ptr += 3; // skip reserved byte and checksum
|
||||
bytestream2_skip(&gb, 3); // skip reserved byte and checksum
|
||||
|
||||
/* check frame dimensions */
|
||||
height = bytestream_get_le16(&buf_ptr);
|
||||
width = bytestream_get_le16(&buf_ptr);
|
||||
height = bytestream2_get_le16(&gb);
|
||||
width = bytestream2_get_le16(&gb);
|
||||
if (av_image_check_size(width, height, 0, avctx))
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
@@ -923,9 +949,10 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
|
||||
avcodec_set_dimensions(avctx, width, height);
|
||||
}
|
||||
|
||||
y_offset = bytestream_get_le32(&buf_ptr);
|
||||
v_offset = bytestream_get_le32(&buf_ptr);
|
||||
u_offset = bytestream_get_le32(&buf_ptr);
|
||||
y_offset = bytestream2_get_le32(&gb);
|
||||
v_offset = bytestream2_get_le32(&gb);
|
||||
u_offset = bytestream2_get_le32(&gb);
|
||||
bytestream2_skip(&gb, 4);
|
||||
|
||||
/* unfortunately there is no common order of planes in the buffer */
|
||||
/* so we use that sorting algo for determining planes data sizes */
|
||||
@@ -944,6 +971,7 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
|
||||
ctx->v_data_size = ends[1] - starts[1];
|
||||
ctx->u_data_size = ends[2] - starts[2];
|
||||
if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 ||
|
||||
FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 ||
|
||||
FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
@@ -952,7 +980,7 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
|
||||
ctx->y_data_ptr = bs_hdr + y_offset;
|
||||
ctx->v_data_ptr = bs_hdr + v_offset;
|
||||
ctx->u_data_ptr = bs_hdr + u_offset;
|
||||
ctx->alt_quant = buf_ptr + sizeof(uint32_t);
|
||||
ctx->alt_quant = gb.buffer;
|
||||
|
||||
if (ctx->data_size == 16) {
|
||||
av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n");
|
||||
|
@@ -1882,6 +1882,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
|
||||
av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order);
|
||||
return -1;
|
||||
}
|
||||
if (s->fft_size != (1 << (s->fft_order - 1))) {
|
||||
av_log(avctx, AV_LOG_ERROR, "FFT size %d not power of 2.\n", s->fft_size);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ff_rdft_init(&s->rdft_ctx, s->fft_order, IDFT_C2R);
|
||||
ff_mpadsp_init(&s->mpadsp);
|
||||
|
@@ -358,6 +358,11 @@ static int rv20_decode_picture_header(MpegEncContext *s)
|
||||
f = get_bits(&s->gb, rpr_bits);
|
||||
|
||||
if(f){
|
||||
if (s->avctx->extradata_size < 8 + 2 * f) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Extradata too small.\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
new_w= 4*((uint8_t*)s->avctx->extradata)[6+2*f];
|
||||
new_h= 4*((uint8_t*)s->avctx->extradata)[7+2*f];
|
||||
}else{
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "libavutil/audioconvert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "avfilter.h"
|
||||
#include "avfiltergraph.h"
|
||||
#include "internal.h"
|
||||
@@ -202,6 +203,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
|
||||
|
||||
for (j = 0; j < filter->input_count; j++) {
|
||||
AVFilterLink *link = filter->inputs[j];
|
||||
|
||||
if (!link) continue;
|
||||
|
||||
if (!link->in_formats || !link->out_formats)
|
||||
@@ -211,8 +213,12 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
|
||||
!avfilter_merge_formats(link->in_formats, link->out_formats)) {
|
||||
|
||||
/* couldn't merge format lists, auto-insert scale filter */
|
||||
snprintf(filt_args, sizeof(filt_args), "0:0:%s",
|
||||
graph->scale_sws_opts);
|
||||
av_strlcpy(filt_args, "0:0", sizeof(filt_args));
|
||||
if (graph->scale_sws_opts) {
|
||||
av_strlcat(filt_args, ":", sizeof(filt_args));
|
||||
av_strlcat(filt_args, graph->scale_sws_opts, sizeof(filt_args));
|
||||
}
|
||||
|
||||
if (ret = insert_conv_filter(graph, link, "scale", filt_args))
|
||||
return ret;
|
||||
}
|
||||
|
@@ -121,7 +121,8 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags")) {
|
||||
if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") &&
|
||||
ctx->scale_sws_opts) {
|
||||
snprintf(tmp_args, sizeof(tmp_args), "%s:%s",
|
||||
args, ctx->scale_sws_opts);
|
||||
args = tmp_args;
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#include "oma.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
|
||||
const uint16_t ff_oma_srate_tab[6] = { 320, 441, 480, 882, 960, 0 };
|
||||
const uint16_t ff_oma_srate_tab[8] = { 320, 441, 480, 882, 960, 0 };
|
||||
|
||||
const AVCodecTag ff_oma_codec_tags[] = {
|
||||
{ CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 },
|
||||
|
@@ -37,7 +37,7 @@ enum {
|
||||
OMA_CODECID_WMA = 5,
|
||||
};
|
||||
|
||||
extern const uint16_t ff_oma_srate_tab[6];
|
||||
extern const uint16_t ff_oma_srate_tab[8];
|
||||
|
||||
extern const AVCodecTag ff_oma_codec_tags[];
|
||||
|
||||
|
@@ -305,7 +305,11 @@ static int oma_read_header(AVFormatContext *s,
|
||||
|
||||
switch (buf[32]) {
|
||||
case OMA_CODECID_ATRAC3:
|
||||
samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100;
|
||||
samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
|
||||
if (!samplerate) {
|
||||
av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (samplerate != 44100)
|
||||
av_log_ask_for_sample(s, "Unsupported sample rate: %d\n",
|
||||
samplerate);
|
||||
@@ -335,9 +339,14 @@ static int oma_read_header(AVFormatContext *s,
|
||||
case OMA_CODECID_ATRAC3P:
|
||||
st->codec->channels = (codec_params >> 10) & 7;
|
||||
framesize = ((codec_params & 0x3FF) * 8) + 8;
|
||||
st->codec->sample_rate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100;
|
||||
st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024;
|
||||
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
|
||||
samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
|
||||
if (!samplerate) {
|
||||
av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
st->codec->sample_rate = samplerate;
|
||||
st->codec->bit_rate = samplerate * framesize * 8 / 1024;
|
||||
avpriv_set_pts_info(st, 64, 1, samplerate);
|
||||
av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
|
||||
break;
|
||||
case OMA_CODECID_MP3:
|
||||
|
@@ -2855,6 +2855,7 @@ void avformat_free_context(AVFormatContext *s)
|
||||
av_free_packet(&st->cur_pkt);
|
||||
}
|
||||
av_dict_free(&st->metadata);
|
||||
av_freep(&st->probe_data.buf);
|
||||
av_freep(&st->index_entries);
|
||||
av_freep(&st->codec->extradata);
|
||||
av_freep(&st->codec->subtitle_header);
|
||||
|
@@ -123,6 +123,15 @@ static int xmv_probe(AVProbeData *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmv_read_close(AVFormatContext *s)
|
||||
{
|
||||
XMVDemuxContext *xmv = s->priv_data;
|
||||
|
||||
av_free(xmv->audio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmv_read_header(AVFormatContext *s,
|
||||
AVFormatParameters *ap)
|
||||
{
|
||||
@@ -133,6 +142,7 @@ static int xmv_read_header(AVFormatContext *s,
|
||||
uint32_t file_version;
|
||||
uint32_t this_packet_size;
|
||||
uint16_t audio_track;
|
||||
int ret;
|
||||
|
||||
avio_skip(pb, 4); /* Next packet size */
|
||||
|
||||
@@ -171,8 +181,10 @@ static int xmv_read_header(AVFormatContext *s,
|
||||
avio_skip(pb, 2); /* Unknown (padding?) */
|
||||
|
||||
xmv->audio = av_malloc(xmv->audio_track_count * sizeof(XMVAudioPacket));
|
||||
if (!xmv->audio)
|
||||
return AVERROR(ENOMEM);
|
||||
if (!xmv->audio) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
|
||||
XMVAudioPacket *packet = &xmv->audio[audio_track];
|
||||
@@ -203,9 +215,18 @@ static int xmv_read_header(AVFormatContext *s,
|
||||
av_log(s, AV_LOG_WARNING, "Unsupported 5.1 ADPCM audio stream "
|
||||
"(0x%04X)\n", packet->flags);
|
||||
|
||||
if (!packet->channels || !packet->sample_rate) {
|
||||
av_log(s, AV_LOG_ERROR, "Invalid parameters for audio track %d.\n",
|
||||
audio_track);
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ast = avformat_new_stream(s, NULL);
|
||||
if (!ast)
|
||||
return AVERROR(ENOMEM);
|
||||
if (!ast) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||
ast->codec->codec_id = packet->codec_id;
|
||||
@@ -231,6 +252,10 @@ static int xmv_read_header(AVFormatContext *s,
|
||||
xmv->stream_count = xmv->audio_track_count + 1;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
xmv_read_close(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void xmv_read_extradata(uint8_t *extradata, AVIOContext *pb)
|
||||
@@ -538,15 +563,6 @@ static int xmv_read_packet(AVFormatContext *s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmv_read_close(AVFormatContext *s)
|
||||
{
|
||||
XMVDemuxContext *xmv = s->priv_data;
|
||||
|
||||
av_free(xmv->audio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVInputFormat ff_xmv_demuxer = {
|
||||
.name = "xmv",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Microsoft XMV"),
|
||||
|
Reference in New Issue
Block a user