summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <[email protected]>2013-08-27 15:37:41 +0200
committerMichael Niedermayer <[email protected]>2013-08-27 15:42:14 +0200
commit465742bbbec4e875b2dae21f8f2e3092113f589c (patch)
tree1966bd4d741119bbfab5efcd3dc6fd14990127aa
parentdaa809fd9f1cb74353f99a1e2817bc5fa68ba076 (diff)
parent5c54fc6195e52c329b88cf5a56d18628f0ee0029 (diff)
Merge commit '5c54fc6195e52c329b88cf5a56d18628f0ee0029' into release/1.1
* commit '5c54fc6195e52c329b88cf5a56d18628f0ee0029': Prepare for 9.8 RELEASE update Changelog smacker: check frame size validity smacker: pad the extradata allocation smacker: check the return value of smacker_decode_tree smacker: fix an off by one in huff.length computation 4xm: do not overread the prestream buffer 4xm: validate the buffer size before parsing it 4xm: reject frames not compatible with the declared version 4xm: drop pointless assert 4xm: forward errors from decode_p_block 4xm: fold last_picture lazy allocation in decode_p_frame 4xm: do not overread while parsing header 4xm: refactor fourxm_read_header 4xm: K&R formatting cosmetics 4xm: use the correct logging context Conflicts: Changelog RELEASE libavcodec/4xm.c libavcodec/smacker.c libavformat/4xm.c libavformat/smacker.c Merged-by: Michael Niedermayer <[email protected]>
-rw-r--r--Changelog21
-rw-r--r--libavcodec/4xm.c110
-rw-r--r--libavcodec/smacker.c15
-rw-r--r--libavformat/4xm.c260
-rw-r--r--libavformat/smacker.c9
5 files changed, 241 insertions, 174 deletions
diff --git a/Changelog b/Changelog
index dfee2e65e8..7723333d30 100644
--- a/Changelog
+++ b/Changelog
@@ -2,6 +2,27 @@ Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest.
version <next>:
+
+Most of the following fixes resulted from test samples that the Google
+Security Team has kindly made available to us:
+
+- 4xm: fix several programming errors to avoid crashes, etc.
+- apetag: use int64_t for filesize
+- jpegls: Fix invalid writes to memory
+- ljpeg: use the correct number of components in YUV
+- mjpeg: Validate sampling factors
+- mjpegdec: properly report unsupported disabled features
+- mjpegdec: validate parameters in mjpeg_decode_scan_progressive_ac
+- mpegvideo: allocate sufficiently large scratch buffer for interlaced vid
+- pixdesc: mark gray8 as pseudopal
+- smacker: fix several programming errors to avoid crashes, etc.
+- tiff: do not overread the source buffer
+- vmd: drop incomplete chunks and spurious samples
+- vmdav: convert to bytestream2 to avoid invalid reads and writes
+- wavpack: check packet size early
+- wavpack: use bytestream2 in wavpack_decode_block
+- wavpack: validate samples size parsed in wavpack_decode_block
+
- aac: check the maximum number of channels to avoid invalid writes
- indeo3: fix off by one in MV validity check
- id3v2: check for end of file while unescaping tags to avoid invalid
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index ee20a529eb..b174e2ab03 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -328,12 +328,12 @@ static inline void mcdc(uint16_t *dst, const uint16_t *src, int log2w,
}
break;
default:
- av_assert2(0);
+ av_assert0(0);
}
}
-static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
- int log2w, int log2h, int stride)
+static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
+ int log2w, int log2h, int stride)
{
const int index = size2index[log2h][log2w];
const int h = 1 << log2h;
@@ -342,57 +342,64 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
BLOCK_TYPE_VLC_BITS, 1);
uint16_t *start = (uint16_t *)f->last_picture.data[0];
uint16_t *end = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
+ int ret;
- av_assert2(code >= 0 && code <= 6);
+ av_assert0(code >= 0 && code <= 6 && log2w >= 0);
if (code == 0) {
if (bytestream2_get_bytes_left(&f->g) < 1) {
av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
- return;
+ return AVERROR_INVALIDDATA;
}
src += f->mv[bytestream2_get_byteu(&f->g)];
if (start > src || src > end) {
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
- return;
+ return AVERROR_INVALIDDATA;
}
mcdc(dst, src, log2w, h, stride, 1, 0);
} else if (code == 1) {
log2h--;
- decode_p_block(f, dst, src, log2w, log2h, stride);
- decode_p_block(f, dst + (stride << log2h),
- src + (stride << log2h), log2w, log2h, stride);
+ if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0)
+ return ret;
+ if ((ret = decode_p_block(f, dst + (stride << log2h),
+ src + (stride << log2h),
+ log2w, log2h, stride)) < 0)
+ return ret;
} else if (code == 2) {
log2w--;
- decode_p_block(f, dst , src, log2w, log2h, stride);
- decode_p_block(f, dst + (1 << log2w),
- src + (1 << log2w), log2w, log2h, stride);
+ if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0)
+ return ret;
+ if ((ret = decode_p_block(f, dst + (1 << log2w),
+ src + (1 << log2w),
+ log2w, log2h, stride)) < 0)
+ return ret;
} else if (code == 3 && f->version < 2) {
mcdc(dst, src, log2w, h, stride, 1, 0);
} else if (code == 4) {
if (bytestream2_get_bytes_left(&f->g) < 1) {
av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
- return;
+ return AVERROR_INVALIDDATA;
}
src += f->mv[bytestream2_get_byteu(&f->g)];
if (start > src || src > end) {
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
- return;
+ return AVERROR_INVALIDDATA;
}
if (bytestream2_get_bytes_left(&f->g2) < 2){
av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
- return;
+ return AVERROR_INVALIDDATA;
}
mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16u(&f->g2));
} else if (code == 5) {
if (bytestream2_get_bytes_left(&f->g2) < 2) {
av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
- return;
+ return AVERROR_INVALIDDATA;
}
mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16u(&f->g2));
} else if (code == 6) {
if (bytestream2_get_bytes_left(&f->g2) < 4) {
av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
- return;
+ return AVERROR_INVALIDDATA;
}
if (log2w) {
dst[0] = bytestream2_get_le16u(&f->g2);
@@ -402,6 +409,7 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
dst[stride] = bytestream2_get_le16u(&f->g2);
}
}
+ return 0;
}
static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
@@ -414,8 +422,20 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
const int stride = f->current_picture.linesize[0] >> 1;
unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
bytestream_offset, wordstream_offset;
+ int ret;
+
+ if (!f->last_picture.data[0]) {
+ if ((ret = ff_get_buffer(f->avctx, &f->last_picture)) < 0) {
+ av_log(f->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ for (y=0; y<f->avctx->height; y++)
+ memset(f->last_picture.data[0] + y*f->last_picture.linesize[0], 0, 2*f->avctx->width);
+ }
if (f->version > 1) {
+ if (length < 20)
+ return AVERROR_INVALIDDATA;
extra = 20;
if (length < extra)
return -1;
@@ -459,7 +479,8 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
for (y = 0; y < height; y += 8) {
for (x = 0; x < width; x += 8)
- decode_p_block(f, dst + x, src + x, 3, 3, stride);
+ if ((ret = decode_p_block(f, dst + x, src + x, 3, 3, stride)) < 0)
+ return ret;
src += 8 * stride;
dst += 8 * stride;
}
@@ -579,7 +600,8 @@ static int decode_i_mb(FourXContext *f)
}
static const uint8_t *read_huffman_tables(FourXContext *f,
- const uint8_t * const buf, int buf_size)
+ const uint8_t * const buf,
+ int buf_size)
{
int frequency[512] = { 0 };
uint8_t flag[512];
@@ -598,8 +620,11 @@ static const uint8_t *read_huffman_tables(FourXContext *f,
for (;;) {
int i;
- if (start <= end && ptr_end - ptr < end - start + 1 + 1)
+ if (ptr_end - ptr < FFMAX(end - start + 1, 0) + 1) {
+ av_log(f->avctx, AV_LOG_ERROR, "invalid data in read_huffman_tables\n");
return NULL;
+ }
+
for (i = start; i <= end; i++)
frequency[i] = *ptr++;
start = *ptr++;
@@ -701,9 +726,9 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
color[1] = bytestream2_get_le16u(&g3);
if (color[0] & 0x8000)
- av_log(NULL, AV_LOG_ERROR, "unk bit 1\n");
+ av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n");
if (color[1] & 0x8000)
- av_log(NULL, AV_LOG_ERROR, "unk bit 2\n");
+ av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n");
color[2] = mix(color[0], color[1]);
color[3] = mix(color[1], color[0]);
@@ -748,7 +773,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
return -1;
}
- prestream = read_huffman_tables(f, prestream, buf + length - prestream);
+ prestream = read_huffman_tables(f, prestream, prestream_size);
if (!prestream) {
av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n");
return AVERROR_INVALIDDATA;
@@ -795,27 +820,35 @@ static int decode_frame(AVCodecContext *avctx, void *data,
AVFrame *p, temp;
int i, frame_4cc, frame_size;
- if (buf_size < 12)
+ if (buf_size < 20)
return AVERROR_INVALIDDATA;
- frame_4cc = AV_RL32(buf);
- if (buf_size != AV_RL32(buf + 4) + 8 || buf_size < 20)
+
+ av_assert0(avctx->width % 16 == 0 && avctx->height % 16 == 0);
+
+ if (buf_size < AV_RL32(buf + 4) + 8) {
av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n",
buf_size, AV_RL32(buf + 4));
+ return AVERROR_INVALIDDATA;
+ }
+
+ frame_4cc = AV_RL32(buf);
if (frame_4cc == AV_RL32("cfrm")) {
int free_index = -1;
+ int id, whole_size;
const int data_size = buf_size - 20;
- const int id = AV_RL32(buf + 12);
- const int whole_size = AV_RL32(buf + 16);
CFrameBuffer *cfrm;
- if (data_size < 0 || whole_size < 0) {
- av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
+ if (f->version <= 1) {
+ av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version);
return AVERROR_INVALIDDATA;
}
- if (f->version <= 1) {
- av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version);
+ id = AV_RL32(buf + 12);
+ whole_size = AV_RL32(buf + 16);
+
+ if (data_size < 0 || whole_size < 0) {
+ av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
return AVERROR_INVALIDDATA;
}
@@ -859,6 +892,9 @@ static int decode_frame(AVCodecContext *avctx, void *data,
av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n",
id, avctx->frame_number);
+ if (f->version <= 1)
+ return AVERROR_INVALIDDATA;
+
cfrm->size = cfrm->id = 0;
frame_4cc = AV_RL32("pfrm");
} else
@@ -897,16 +933,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
return -1;
}
} else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
- if (!f->last_picture.data[0]) {
- f->last_picture.reference = 3;
- if (ff_get_buffer(avctx, &f->last_picture) < 0) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
- return -1;
- }
- for (i=0; i<avctx->height; i++)
- memset(f->last_picture.data[0] + i*f->last_picture.linesize[0], 0, 2*avctx->width);
- }
-
p->pict_type = AV_PICTURE_TYPE_P;
if (decode_p_frame(f, buf, frame_size) < 0) {
av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index 5765c1568c..88b2b9c004 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -257,7 +257,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
ctx.recode2 = tmp2.values;
ctx.last = last;
- huff.length = ((size + 3) >> 2) + 3;
+ huff.length = ((size + 3) >> 2) + 4;
huff.maxlength = 0;
huff.current = 0;
huff.values = av_mallocz(huff.length * sizeof(int));
@@ -661,9 +661,16 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
h[i].lengths = av_mallocz(256 * sizeof(int));
h[i].values = av_mallocz(256 * sizeof(int));
skip_bits1(&gb);
- res = smacker_decode_tree(&gb, &h[i], 0, 0);
- if (res < 0)
- return res;
+ if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) {
+ for (; i >= 0; i--) {
+ if (vlc[i].table)
+ ff_free_vlc(&vlc[i]);
+ av_free(h[i].bits);
+ av_free(h[i].lengths);
+ av_free(h[i].values);
+ }
+ return AVERROR_INVALIDDATA;
+ }
skip_bits1(&gb);
if(h[i].current > 1) {
res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length,
diff --git a/libavformat/4xm.c b/libavformat/4xm.c
index 1e142f550f..9eb46e7d64 100644
--- a/libavformat/4xm.c
+++ b/libavformat/4xm.c
@@ -57,7 +57,7 @@
#define GET_LIST_HEADER() \
fourcc_tag = avio_rl32(pb); \
- size = avio_rl32(pb); \
+ size = avio_rl32(pb); \
if (fourcc_tag != LIST_TAG) \
return AVERROR_INVALIDDATA; \
fourcc_tag = avio_rl32(pb);
@@ -72,8 +72,6 @@ typedef struct AudioTrack {
} AudioTrack;
typedef struct FourxmDemuxContext {
- int width;
- int height;
int video_stream_index;
int track_count;
AudioTrack *tracks;
@@ -91,6 +89,108 @@ static int fourxm_probe(AVProbeData *p)
return AVPROBE_SCORE_MAX;
}
+static int parse_vtrk(AVFormatContext *s,
+ FourxmDemuxContext *fourxm, uint8_t *buf, int size,
+ int left)
+{
+ AVStream *st;
+ /* check that there is enough data */
+ if (size != vtrk_SIZE || left < size + 8) {
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* allocate a new AVStream */
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ avpriv_set_pts_info(st, 60, 1, fourxm->fps);
+
+ fourxm->video_stream_index = st->index;
+
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = AV_CODEC_ID_4XM;
+ st->codec->extradata_size = 4;
+ st->codec->extradata = av_malloc(4);
+ AV_WL32(st->codec->extradata, AV_RL32(buf + 16));
+ st->codec->width = AV_RL32(buf + 36);
+ st->codec->height = AV_RL32(buf + 40);
+
+ return 0;
+}
+
+
+static int parse_strk(AVFormatContext *s,
+ FourxmDemuxContext *fourxm, uint8_t *buf, int size,
+ int left)
+{
+ AVStream *st;
+ int track;
+ /* check that there is enough data */
+ if (size != strk_SIZE || left < size + 8)
+ return AVERROR_INVALIDDATA;
+
+ track = AV_RL32(buf + 8);
+ if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) {
+ av_log(s, AV_LOG_ERROR, "current_track too large\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (track + 1 > fourxm->track_count) {
+ fourxm->tracks = av_realloc_f(fourxm->tracks, track + 1, sizeof(AudioTrack));
+ if (!fourxm->tracks)
+ return AVERROR(ENOMEM);
+ memset(&fourxm->tracks[fourxm->track_count], 0,
+ sizeof(AudioTrack) * (track + 1 - fourxm->track_count));
+ fourxm->track_count = track + 1;
+ }
+ fourxm->tracks[track].adpcm = AV_RL32(buf + 12);
+ fourxm->tracks[track].channels = AV_RL32(buf + 36);
+ fourxm->tracks[track].sample_rate = AV_RL32(buf + 40);
+ fourxm->tracks[track].bits = AV_RL32(buf + 44);
+ fourxm->tracks[track].audio_pts = 0;
+
+ if (fourxm->tracks[track].channels <= 0 ||
+ fourxm->tracks[track].sample_rate <= 0 ||
+ fourxm->tracks[track].bits < 0) {
+ av_log(s, AV_LOG_ERROR, "audio header invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!fourxm->tracks[track].adpcm && fourxm->tracks[track].bits<8) {
+ av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* allocate a new AVStream */
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ st->id = track;
+ avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate);
+
+ fourxm->tracks[track].stream_index = st->index;
+
+ st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codec->codec_tag = 0;
+ st->codec->channels = fourxm->tracks[track].channels;
+ st->codec->sample_rate = fourxm->tracks[track].sample_rate;
+ st->codec->bits_per_coded_sample = fourxm->tracks[track].bits;
+ st->codec->bit_rate = st->codec->channels *
+ st->codec->sample_rate *
+ st->codec->bits_per_coded_sample;
+ st->codec->block_align = st->codec->channels *
+ st->codec->bits_per_coded_sample;
+
+ if (fourxm->tracks[track].adpcm){
+ st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
+ } else if (st->codec->bits_per_coded_sample == 8) {
+ st->codec->codec_id = AV_CODEC_ID_PCM_U8;
+ } else
+ st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
+
+ return 0;
+}
+
static int fourxm_read_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
@@ -100,11 +200,10 @@ static int fourxm_read_header(AVFormatContext *s)
FourxmDemuxContext *fourxm = s->priv_data;
unsigned char *header;
int i, ret;
- AVStream *st;
fourxm->track_count = 0;
- fourxm->tracks = NULL;
- fourxm->fps = 1.0;
+ fourxm->tracks = NULL;
+ fourxm->fps = 1.0;
/* skip the first 3 32-bit numbers */
avio_skip(pb, 12);
@@ -119,7 +218,7 @@ static int fourxm_read_header(AVFormatContext *s)
header = av_malloc(header_size);
if (!header)
return AVERROR(ENOMEM);
- if (avio_read(pb, header, header_size) != header_size){
+ if (avio_read(pb, header, header_size) != header_size) {
av_free(header);
return AVERROR(EIO);
}
@@ -127,123 +226,38 @@ static int fourxm_read_header(AVFormatContext *s)
/* take the lazy approach and search for any and all vtrk and strk chunks */
for (i = 0; i < header_size - 8; i++) {
fourcc_tag = AV_RL32(&header[i]);
- size = AV_RL32(&header[i + 4]);
+ size = AV_RL32(&header[i + 4]);
if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) {
av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8);
return AVERROR_INVALIDDATA;
}
if (fourcc_tag == std__TAG) {
- if (header_size < i + 16) {
+ if (header_size - i < 16) {
av_log(s, AV_LOG_ERROR, "std TAG truncated\n");
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
}
fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
} else if (fourcc_tag == vtrk_TAG) {
- /* check that there is enough data */
- if (size != vtrk_SIZE) {
- ret= AVERROR_INVALIDDATA;
+ if ((ret = parse_vtrk(s, fourxm, header + i, size,
+ header_size - i)) < 0)
goto fail;
- }
- fourxm->width = AV_RL32(&header[i + 36]);
- fourxm->height = AV_RL32(&header[i + 40]);
-
- /* allocate a new AVStream */
- st = avformat_new_stream(s, NULL);
- if (!st){
- ret= AVERROR(ENOMEM);
- goto fail;
- }
- avpriv_set_pts_info(st, 60, 1, fourxm->fps);
-
- fourxm->video_stream_index = st->index;
-
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = AV_CODEC_ID_4XM;
- st->codec->extradata_size = 4;
- st->codec->extradata = av_malloc(4);
- AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));
- st->codec->width = fourxm->width;
- st->codec->height = fourxm->height;
i += 8 + size;
} else if (fourcc_tag == strk_TAG) {
- int current_track;
- /* check that there is enough data */
- if (size != strk_SIZE) {
- ret= AVERROR_INVALIDDATA;
- goto fail;
- }
- current_track = AV_RL32(&header[i + 8]);
- if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){
- av_log(s, AV_LOG_ERROR, "current_track too large\n");
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- if (current_track + 1 > fourxm->track_count) {
- fourxm->tracks = av_realloc_f(fourxm->tracks,
- sizeof(AudioTrack),
- current_track + 1);
- if (!fourxm->tracks) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- memset(&fourxm->tracks[fourxm->track_count], 0,
- sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count));
- fourxm->track_count = current_track + 1;
- }
- fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);
- fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);
- fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);
- fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]);
- fourxm->tracks[current_track].audio_pts = 0;
- if( fourxm->tracks[current_track].channels <= 0
- || fourxm->tracks[current_track].sample_rate <= 0
- || fourxm->tracks[current_track].bits < 0){
- av_log(s, AV_LOG_ERROR, "audio header invalid\n");
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){
- av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
- ret = AVERROR_INVALIDDATA;
+ if ((ret = parse_strk(s, fourxm, header + i, size,
+ header_size - i)) < 0)
goto fail;
- }
- i += 8 + size;
- /* allocate a new AVStream */
- st = avformat_new_stream(s, NULL);
- if (!st){
- ret= AVERROR(ENOMEM);
- goto fail;
- }
-
- st->id = current_track;
- avpriv_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);
-
- fourxm->tracks[current_track].stream_index = st->index;
-
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->codec_tag = 0;
- st->codec->channels = fourxm->tracks[current_track].channels;
- st->codec->sample_rate = fourxm->tracks[current_track].sample_rate;
- st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;
- st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
- st->codec->bits_per_coded_sample;
- st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
- if (fourxm->tracks[current_track].adpcm){
- st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
- }else if (st->codec->bits_per_coded_sample == 8){
- st->codec->codec_id = AV_CODEC_ID_PCM_U8;
- }else
- st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
+ i += 8 + size;
}
}
/* skip over the LIST-MOVI chunk (which is where the stream should be */
GET_LIST_HEADER();
- if (fourcc_tag != MOVI_TAG){
- ret= AVERROR_INVALIDDATA;
+ if (fourcc_tag != MOVI_TAG) {
+ ret = AVERROR_INVALIDDATA;
goto fail;
}
@@ -262,7 +276,7 @@ static int fourxm_read_packet(AVFormatContext *s,
AVPacket *pkt)
{
FourxmDemuxContext *fourxm = s->priv_data;
- AVIOContext *pb = s->pb;
+ AVIOContext *pb = s->pb;
unsigned int fourcc_tag;
unsigned int size;
int ret = 0;
@@ -272,18 +286,16 @@ static int fourxm_read_packet(AVFormatContext *s,
int audio_frame_count;
while (!packet_read) {
-
if ((ret = avio_read(s->pb, header, 8)) < 0)
return ret;
fourcc_tag = AV_RL32(&header[0]);
- size = AV_RL32(&header[4]);
+ size = AV_RL32(&header[4]);
if (url_feof(pb))
return AVERROR(EIO);
switch (fourcc_tag) {
-
case LIST_TAG:
/* this is a good time to bump the video pts */
- fourxm->video_pts ++;
+ fourxm->video_pts++;
/* skip the LIST-* tag and move on to the next fourcc */
avio_rl32(pb);
@@ -300,45 +312,43 @@ static int fourxm_read_packet(AVFormatContext *s,
if (size + 8 < size || av_new_packet(pkt, size + 8))
return AVERROR(EIO);
pkt->stream_index = fourxm->video_stream_index;
- pkt->pts = fourxm->video_pts;
- pkt->pos = avio_tell(s->pb);
+ pkt->pts = fourxm->video_pts;
+ pkt->pos = avio_tell(s->pb);
memcpy(pkt->data, header, 8);
ret = avio_read(s->pb, &pkt->data[8], size);
- if (ret < 0){
+ if (ret < 0) {
av_free_packet(pkt);
- }else
+ } else
packet_read = 1;
break;
case snd__TAG:
track_number = avio_rl32(pb);
avio_skip(pb, 4);
- size-=8;
+ size -= 8;
- if (track_number < fourxm->track_count && fourxm->tracks[track_number].channels>0) {
- ret= av_get_packet(s->pb, pkt, size);
- if(ret<0)
+ if (track_number < fourxm->track_count &&
+ fourxm->tracks[track_number].channels > 0) {
+ ret = av_get_packet(s->pb, pkt, size);
+ if (ret < 0)
return AVERROR(EIO);
pkt->stream_index =
fourxm->tracks[track_number].stream_index;
- pkt->pts = fourxm->tracks[track_number].audio_pts;
+ pkt->pts = fourxm->tracks[track_number].audio_pts;
packet_read = 1;
/* pts accounting */
audio_frame_count = size;
if (fourxm->tracks[track_number].adpcm)
- audio_frame_count -=
- 2 * (fourxm->tracks[track_number].channels);
- audio_frame_count /=
- fourxm->tracks[track_number].channels;
- if (fourxm->tracks[track_number].adpcm){
+ audio_frame_count -= 2 * (fourxm->tracks[track_number].channels);
+ audio_frame_count /= fourxm->tracks[track_number].channels;
+ if (fourxm->tracks[track_number].adpcm) {
audio_frame_count *= 2;
- }else
+ } else
audio_frame_count /=
- (fourxm->tracks[track_number].bits / 8);
+ (fourxm->tracks[track_number].bits / 8);
fourxm->tracks[track_number].audio_pts += audio_frame_count;
-
} else {
avio_skip(pb, size);
}
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index 84481e22a6..aa66312bda 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -210,7 +210,8 @@ static int smacker_read_header(AVFormatContext *s)
/* load trees to extradata, they will be unpacked by decoder */
- st->codec->extradata = av_malloc(smk->treesize + 16 + FF_INPUT_BUFFER_PADDING_SIZE);
+ st->codec->extradata = av_mallocz(smk->treesize + 16 +
+ FF_INPUT_BUFFER_PADDING_SIZE);
st->codec->extradata_size = smk->treesize + 16;
if(!st->codec->extradata){
av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
@@ -305,12 +306,14 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
/* if audio chunks are present, put them to stack and retrieve later */
for(i = 0; i < 7; i++) {
if(flags & 1) {
- unsigned int size;
+ uint32_t size;
uint8_t *tmpbuf;
size = avio_rl32(s->pb) - 4;
- if(size + 4L > frame_size)
+ if (!size || size + 4L > frame_size) {
+ av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
return AVERROR_INVALIDDATA;
+ }
frame_size -= size;
frame_size -= 4;
smk->curstream++;