[SCM] libav/experimental: Imported Upstream version 9.5

siretart at users.alioth.debian.org siretart at users.alioth.debian.org
Mon May 27 20:38:49 UTC 2013


The following commit has been merged in the experimental branch:
commit 58df3eb21f8fb5cf3aebe6b544eeac8e8339e8b4
Author: Reinhard Tartler <siretart at tauware.de>
Date:   Thu Apr 25 22:30:11 2013 +0200

    Imported Upstream version 9.5

diff --git a/Changelog b/Changelog
index b7f7e94..ca9db5a 100644
--- a/Changelog
+++ b/Changelog
@@ -1,6 +1,36 @@
 Entries are sorted chronologically from oldest to youngest within each release,
 releases are sorted from youngest to oldest.
 
+version 9.5:
+
+Most of the following fixes resulted from test samples that the Google
+Security Team has kindly made available to us:
+
+- af_channelmap: sanity check input channel indices in all cases
+- avfiltergraph: check for sws opts being non-NULL before using them
+- bmv: check for len being valid in bmv_decode_frame()
+- configure: Enable hwaccels without external dependencies by default
+- dfa: check for invalid access in decode_wdlt()
+- id3v2: pad the APIC packets as required by lavc
+- indeo3: check motion vectors
+- indeo3: fix data size check
+- indeo3: switch parsing the header to bytestream2
+- lavf: make sure stream probe data gets freed
+- matroska: Update the available size after lace parsing
+- matroska: fix a corner case in ebml-lace parsing
+- matroska: pass the lace size to the matroska_parse_rm_audio
+- mp3dec: fallback to generic seeking when a TOC is not present
+- oggdec: fix faulty cleanup prototype
+- oma: Validate sample rates
+- qdm2: check that the FFT size is a power of 2
+- riff: check for eof if chunk size and code are 0 to prevent an infinite loop
+- rv10: check that extradata is large enough
+- svq1dec: check that the reference frame has the same dimensions as the current one
+- svq1dec: clip motion vectors to the frame size
+- xmv: check audio track parameters validity
+- xmv: do not leak memory in the error paths in xmv_read_header()
+
+
 version 9.4:
 - atrac3: avoid oversized shifting in decode_bytes()
 - eamad: allocate a dummy reference frame when the real one is missing
diff --git a/RELEASE b/RELEASE
index 0359f24..592f36e 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-9.4
+9.5
diff --git a/VERSION b/VERSION
index 0359f24..592f36e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-9.4
+9.5
diff --git a/configure b/configure
index aa31ea0..6ab04ae 100755
--- a/configure
+++ b/configure
@@ -1604,25 +1604,26 @@ zmbv_decoder_select="zlib"
 zmbv_encoder_select="zlib"
 
 # hardware accelerators
+dxva2_deps="dxva2api_h"
 vaapi_deps="va_va_h"
 vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
 vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
 
 h263_vaapi_hwaccel_select="vaapi h263_decoder"
-h264_dxva2_hwaccel_deps="dxva2api_h"
-h264_dxva2_hwaccel_select="dxva2 h264_decoder"
+h264_dxva2_hwaccel_deps="dxva2"
+h264_dxva2_hwaccel_select="h264_decoder"
 h264_vaapi_hwaccel_select="vaapi h264_decoder"
 h264_vda_hwaccel_select="vda h264_decoder"
 h264_vdpau_decoder_select="vdpau h264_decoder"
 mpeg_vdpau_decoder_select="vdpau mpegvideo_decoder"
 mpeg1_vdpau_decoder_select="vdpau mpeg1video_decoder"
-mpeg2_dxva2_hwaccel_deps="dxva2api_h"
-mpeg2_dxva2_hwaccel_select="dxva2 mpeg2video_decoder"
+mpeg2_dxva2_hwaccel_deps="dxva2"
+mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
 mpeg2_vaapi_hwaccel_select="vaapi mpeg2video_decoder"
 mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder"
 mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder"
-vc1_dxva2_hwaccel_deps="dxva2api_h"
-vc1_dxva2_hwaccel_select="dxva2 vc1_decoder"
+vc1_dxva2_hwaccel_deps="dxva2"
+vc1_dxva2_hwaccel_select="vc1_decoder"
 vc1_vaapi_hwaccel_select="vaapi vc1_decoder"
 vc1_vdpau_decoder_select="vdpau vc1_decoder"
 wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
@@ -1844,6 +1845,9 @@ enable safe_bitstream_reader
 enable static
 enable swscale_alpha
 
+# By default, enable only those hwaccels that have no external dependencies.
+enable dxva2 vdpau
+
 # build settings
 SHFLAGS='-shared -Wl,-soname,$$(@F)'
 AVSERVERLDFLAGS=-Wl,-E
diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c
index a7f21ec..bcb1380 100644
--- a/libavcodec/bmv.c
+++ b/libavcodec/bmv.c
@@ -136,7 +136,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:
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 119be70..332a53e 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -257,6 +257,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--) {
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 261c651..eacd150 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -223,7 +223,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;
@@ -233,6 +233,16 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
     dst         = plane->pixels[ctx->buf_sel] + offset_dst;
     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      = offset_dst + mv_y * plane->pitch + mv_x;
     src         = plane->pixels[ctx->buf_sel ^ 1] + offset;
 
@@ -260,6 +270,8 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
             dst += 4;
         }
     }
+
+    return 0;
 }
 
 
@@ -585,11 +597,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;
     }
@@ -721,7 +745,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");
@@ -772,8 +796,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:
@@ -856,17 +880,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");
@@ -874,28 +901,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;
 
@@ -921,9 +947,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  */
@@ -942,6 +969,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;
@@ -950,7 +978,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");
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index cfae824..17729d1 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -1838,6 +1838,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);
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 9239cf7..26af29f 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -347,6 +347,11 @@ static int rv20_decode_picture_header(RVDecContext *rv)
         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{
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index 5156042..82f9301 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -322,7 +322,8 @@ static void svq1_skip_block(uint8_t *current, uint8_t *previous,
 
 static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf,
                                    uint8_t *current, uint8_t *previous,
-                                   int pitch, svq1_pmv *motion, int x, int y)
+                                   int pitch, svq1_pmv *motion, int x, int y,
+                                   int width, int height)
 {
     uint8_t *src;
     uint8_t *dst;
@@ -352,10 +353,8 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf,
     motion[x / 8 + 2].y =
     motion[x / 8 + 3].y = mv.y;
 
-    if (y + (mv.y >> 1) < 0)
-        mv.y = 0;
-    if (x + (mv.x >> 1) < 0)
-        mv.x = 0;
+    mv.x = av_clip(mv.x, -2 * x, 2 * (width  - x - 16));
+    mv.y = av_clip(mv.y, -2 * y, 2 * (height - y - 16));
 
     src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch];
     dst = current;
@@ -367,7 +366,8 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf,
 
 static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf,
                                       uint8_t *current, uint8_t *previous,
-                                      int pitch, svq1_pmv *motion, int x, int y)
+                                      int pitch, svq1_pmv *motion, int x, int y,
+                                      int width, int height)
 {
     uint8_t *src;
     uint8_t *dst;
@@ -427,10 +427,8 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf,
         int mvy = pmv[i]->y + (i >> 1) * 16;
 
         // FIXME: clipping or padding?
-        if (y + (mvy >> 1) < 0)
-            mvy = 0;
-        if (x + (mvx >> 1) < 0)
-            mvx = 0;
+        mvx = av_clip(mvx, -2 * x, 2 * (width  - x - 8));
+        mvy = av_clip(mvy, -2 * y, 2 * (height - y - 8));
 
         src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch];
         dst = current;
@@ -450,7 +448,8 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf,
 static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp,
                                    GetBitContext *bitbuf,
                                    uint8_t *current, uint8_t *previous,
-                                   int pitch, svq1_pmv *motion, int x, int y)
+                                   int pitch, svq1_pmv *motion, int x, int y,
+                                   int width, int height)
 {
     uint32_t block_type;
     int result = 0;
@@ -475,7 +474,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp,
 
     case SVQ1_BLOCK_INTER:
         result = svq1_motion_inter_block(dsp, bitbuf, current, previous,
-                                         pitch, motion, x, y);
+                                         pitch, motion, x, y, width, height);
 
         if (result != 0) {
             av_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result);
@@ -486,7 +485,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp,
 
     case SVQ1_BLOCK_INTER_4V:
         result = svq1_motion_inter_4v_block(dsp, bitbuf, current, previous,
-                                            pitch, motion, x, y);
+                                            pitch, motion, x, y, width, height);
 
         if (result != 0) {
             av_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result);
@@ -692,7 +691,8 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
         } else {
             /* delta frame */
             uint8_t *previous = s->prev->data[i];
-            if (!previous) {
+            if (!previous ||
+                s->prev->width != s->width || s->prev->height != s->height) {
                 av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
                 result = AVERROR_INVALIDDATA;
                 goto err;
@@ -705,7 +705,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
                     result = svq1_decode_delta_block(avctx, &s->dsp,
                                                      &s->gb, &current[x],
                                                      previous, linesize,
-                                                     pmv, x, y);
+                                                     pmv, x, y, width, height);
                     if (result != 0) {
                         av_dlog(avctx,
                                 "Error in svq1_decode_delta_block %i\n",
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 3b8f7d2..deb5015 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -40,6 +40,10 @@ static void free_buffers(VP8Context *s)
     int i;
     if (s->thread_data)
         for (i = 0; i < MAX_THREADS; i++) {
+#if HAVE_THREADS
+            pthread_cond_destroy(&s->thread_data[i].cond);
+            pthread_mutex_destroy(&s->thread_data[i].lock);
+#endif
             av_freep(&s->thread_data[i].filter_strength);
             av_freep(&s->thread_data[i].edge_emu_buffer);
         }
diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
index 8b72d5b..c4b87da 100644
--- a/libavfilter/af_channelmap.c
+++ b/libavfilter/af_channelmap.c
@@ -362,23 +362,32 @@ static int channelmap_config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
     ChannelMapContext *s = ctx->priv;
+    int nb_channels = av_get_channel_layout_nb_channels(inlink->channel_layout);
     int i, err = 0;
     const char *channel_name;
     char layout_name[256];
 
-    if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) {
-        for (i = 0; i < s->nch; i++) {
+    for (i = 0; i < s->nch; i++) {
+        if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) {
             s->map[i].in_channel_idx = av_get_channel_layout_channel_index(
                 inlink->channel_layout, s->map[i].in_channel);
-            if (s->map[i].in_channel_idx < 0) {
+        }
+
+        if (s->map[i].in_channel_idx < 0 ||
+            s->map[i].in_channel_idx >= nb_channels) {
+            av_get_channel_layout_string(layout_name, sizeof(layout_name),
+                                         0, inlink->channel_layout);
+            if (s->map[i].in_channel) {
                 channel_name = av_get_channel_name(s->map[i].in_channel);
-                av_get_channel_layout_string(layout_name, sizeof(layout_name),
-                                             0, inlink->channel_layout);
                 av_log(ctx, AV_LOG_ERROR,
                        "input channel '%s' not available from input layout '%s'\n",
                        channel_name, layout_name);
-                err = AVERROR(EINVAL);
+            } else {
+                av_log(ctx, AV_LOG_ERROR,
+                       "input channel #%d not available from input layout '%s'\n",
+                       s->map[i].in_channel_idx, layout_name);
             }
+            err = AVERROR(EINVAL);
         }
     }
 
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index f5c9984..d27b1b2 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -24,6 +24,7 @@
 #include <string.h>
 
 #include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/log.h"
@@ -220,7 +221,11 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
 
                     snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
                              scaler_count++);
-                    snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
+                    av_strlcpy(scale_args, "0:0", sizeof(scale_args));
+                    if (graph->scale_sws_opts) {
+                        av_strlcat(scale_args, ":", sizeof(scale_args));
+                        av_strlcat(scale_args, graph->scale_sws_opts, sizeof(scale_args));
+                    }
                     if ((ret = avfilter_graph_create_filter(&convert, filter,
                                                             inst_name, scale_args, NULL,
                                                             graph)) < 0)
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index 04339c8..7ce60c1 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -123,7 +123,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;
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 403a9b5..2f68653 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -400,7 +400,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
         acodec = astream ? astream->codec : NULL;
         vcodec = vstream ? vstream->codec : NULL;
 
-        if (amf_type == AMF_DATA_TYPE_NUMBER) {
+        if (amf_type == AMF_DATA_TYPE_NUMBER || amf_type == AMF_DATA_TYPE_BOOL) {
             if (!strcmp(key, "duration"))
                 s->duration = num_val * AV_TIME_BASE;
             else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
@@ -417,10 +417,18 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
                     flv_set_video_codec(s, vstream, num_val, 0);
                 } else
                 if (!strcmp(key, "audiocodecid") && acodec) {
-                    flv_set_audio_codec(s, astream, acodec, num_val);
+                    int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET;
+                    flv_set_audio_codec(s, astream, acodec, id);
                 } else
                 if (!strcmp(key, "audiosamplerate") && acodec) {
                     acodec->sample_rate = num_val;
+                } else if (!strcmp(key, "audiosamplesize") && acodec) {
+                    acodec->bits_per_coded_sample = num_val;
+                } else if (!strcmp(key, "stereo") && acodec) {
+                    acodec->channels = num_val + 1;
+                    acodec->channel_layout = acodec->channels == 2 ?
+                                             AV_CH_LAYOUT_STEREO :
+                                             AV_CH_LAYOUT_MONO;
                 } else
                 if (!strcmp(key, "width") && vcodec) {
                     vcodec->width = num_val;
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 4516ac7..7f39a47 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -477,9 +477,10 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag
     }
 
     apic->len   = taglen;
-    apic->data  = av_malloc(taglen);
+    apic->data  = av_malloc(taglen + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!apic->data || avio_read(pb, apic->data, taglen) != taglen)
         goto fail;
+    memset(apic->data + taglen, 0, FF_INPUT_BUFFER_PADDING_SIZE);
 
     new_extra->tag    = "APIC";
     new_extra->data   = apic;
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 86ff477..147c24c 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1757,10 +1757,10 @@ static void matroska_clear_queue(MatroskaDemuxContext *matroska)
 }
 
 static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
-                                int size, int type,
+                                int* buf_size, int type,
                                 uint32_t **lace_buf, int *laces)
 {
-    int res = 0, n;
+    int res = 0, n, size = *buf_size;
     uint8_t *data = *buf;
     uint32_t *lace_size;
 
@@ -1821,7 +1821,7 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
 
     case 0x3: /* EBML lacing */ {
         uint64_t num;
-        uint32_t total;
+        uint64_t total;
         n = matroska_ebmlnum_uint(matroska, data, size, &num);
         if (n < 0) {
             av_log(matroska->ctx, AV_LOG_INFO,
@@ -1858,6 +1858,7 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
 
     *buf      = data;
     *lace_buf = lace_size;
+    *buf_size = size;
 
     return res;
 }
@@ -2052,7 +2053,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
         matroska->skip_to_keyframe = 0;
     }
 
-    res = matroska_parse_laces(matroska, &data, size, (flags & 0x06) >> 1,
+    res = matroska_parse_laces(matroska, &data, &size, (flags & 0x06) >> 1,
                                &lace_size, &laces);
 
     if (res)
@@ -2080,7 +2081,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
              st->codec->codec_id == AV_CODEC_ID_ATRAC3) &&
              st->codec->block_align && track->audio.sub_packet_size) {
 
-            res = matroska_parse_rm_audio(matroska, track, st, data, size,
+            res = matroska_parse_rm_audio(matroska, track, st, data,
+                                          lace_size[n],
                                           timecode, duration, pos);
             if (res)
                 goto end;
@@ -2096,7 +2098,6 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
         if (timecode != AV_NOPTS_VALUE)
             timecode = duration ? timecode + duration : AV_NOPTS_VALUE;
         data += lace_size[n];
-        size -= lace_size[n];
     }
 
 end:
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 48deefd..9da9aa8 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -35,6 +35,10 @@
 
 #define XING_TOC_COUNT 100
 
+typedef struct MP3DecContext {
+    int xing_toc;
+} MP3DecContext;
+
 /* mp3 read */
 
 static int mp3_read_probe(AVProbeData *p)
@@ -100,6 +104,7 @@ static int mp3_read_probe(AVProbeData *p)
 static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration)
 {
     int i;
+    MP3DecContext *mp3 = s->priv_data;
 
     if (!filesize &&
         !(filesize = avio_size(s->pb))) {
@@ -115,6 +120,7 @@ static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration
                            av_rescale(i, duration, XING_TOC_COUNT),
                            0, 0, AVINDEX_KEYFRAME);
     }
+    mp3->xing_toc = 1;
 }
 
 /**
@@ -238,11 +244,15 @@ static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt)
 static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
                     int flags)
 {
+    MP3DecContext *mp3 = s->priv_data;
     AVIndexEntry *ie;
     AVStream *st = s->streams[0];
     int64_t ret  = av_index_search_timestamp(st, timestamp, flags);
     uint32_t header = 0;
 
+    if (!mp3->xing_toc)
+        return AVERROR(ENOSYS);
+
     if (ret < 0)
         return ret;
 
@@ -270,6 +280,7 @@ AVInputFormat ff_mp3_demuxer = {
     .read_header    = mp3_read_header,
     .read_packet    = mp3_read_packet,
     .read_seek      = mp3_seek,
+    .priv_data_size = sizeof(MP3DecContext),
     .flags          = AVFMT_GENERIC_INDEX,
     .extensions     = "mp2,mp3,m2a", /* XXX: use probe */
 };
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index fbe6c4f..bb41b52 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -192,7 +192,7 @@ fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
     return offset;
 }
 
-static int vorbis_cleanup(AVFormatContext *s, int idx)
+static void vorbis_cleanup(AVFormatContext *s, int idx)
 {
     struct ogg *ogg = s->priv_data;
     struct ogg_stream *os = ogg->streams + idx;
diff --git a/libavformat/oma.c b/libavformat/oma.c
index f6454d9..aaaf0b2 100644
--- a/libavformat/oma.c
+++ b/libavformat/oma.c
@@ -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[] = {
     { AV_CODEC_ID_ATRAC3,      OMA_CODECID_ATRAC3  },
diff --git a/libavformat/oma.h b/libavformat/oma.h
index bac8bcb..1f0ddf9 100644
--- a/libavformat/oma.h
+++ b/libavformat/oma.h
@@ -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[];
 
diff --git a/libavformat/omadec.c b/libavformat/omadec.c
index 2e565c1..f6b6f13 100644
--- a/libavformat/omadec.c
+++ b/libavformat/omadec.c
@@ -304,7 +304,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:
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 79b2670..e9463c0 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -728,6 +728,10 @@ int ff_read_riff_info(AVFormatContext *s, int64_t size)
         if (!chunk_code) {
             if (chunk_size)
                 avio_skip(pb, chunk_size);
+            else if (pb->eof_reached) {
+                av_log(s, AV_LOG_WARNING, "truncated file\n");
+                return AVERROR_EOF;
+            }
             continue;
         }
 
diff --git a/libavformat/utils.c b/libavformat/utils.c
index cd46caf..085ae83 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2671,6 +2671,7 @@ void avformat_free_context(AVFormatContext *s)
         if (st->attached_pic.data)
             av_free_packet(&st->attached_pic);
         av_dict_free(&st->metadata);
+        av_freep(&st->probe_data.buf);
         av_free(st->index_entries);
         av_free(st->codec->extradata);
         av_free(st->codec->subtitle_header);
diff --git a/libavformat/xmv.c b/libavformat/xmv.c
index 3f926ef..d491dec 100644
--- a/libavformat/xmv.c
+++ b/libavformat/xmv.c
@@ -126,6 +126,16 @@ static int xmv_probe(AVProbeData *p)
     return 0;
 }
 
+static int xmv_read_close(AVFormatContext *s)
+{
+    XMVDemuxContext *xmv = s->priv_data;
+
+    av_free(xmv->audio);
+    av_free(xmv->audio_tracks);
+
+    return 0;
+}
+
 static int xmv_read_header(AVFormatContext *s)
 {
     XMVDemuxContext *xmv = s->priv_data;
@@ -135,6 +145,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 */
 
@@ -177,8 +188,10 @@ static int xmv_read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
 
     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++) {
         XMVAudioTrack  *track  = &xmv->audio_tracks[audio_track];
@@ -211,9 +224,18 @@ static int xmv_read_header(AVFormatContext *s)
             av_log(s, AV_LOG_WARNING, "Unsupported 5.1 ADPCM audio stream "
                                       "(0x%04X)\n", track->flags);
 
+        if (!track->channels || !track->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              = track->codec_id;
@@ -239,6 +261,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)
@@ -546,16 +572,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);
-    av_free(xmv->audio_tracks);
-
-    return 0;
-}
-
 AVInputFormat ff_xmv_demuxer = {
     .name           = "xmv",
     .long_name      = NULL_IF_CONFIG_SMALL("Microsoft XMV"),

-- 
Libav/FFmpeg packaging



More information about the pkg-multimedia-commits mailing list