[SCM] libav/experimental: Detect and prevent reading over the end of counts_*. We pass the error through a context variable as this is simpler and i think also faster, but the return value of functions could be used instead of course. The code also ensures as a side effect that the AC decoder state does not become invalid. This fixes all known crashes. And outputs nothing in case of an error instead of random noise.

siretart at users.alioth.debian.org siretart at users.alioth.debian.org
Sun Jun 30 16:16:16 UTC 2013


The following commit has been merged in the experimental branch:
commit 6a287b739f3a8660d5e4405be1302da8b3e51e88
Author: Michael Niedermayer <michaelni at gmx.at>
Date:   Tue Mar 4 21:58:34 2008 +0000

    Detect and prevent reading over the end of counts_*. We pass the error
    through a context variable as this is simpler and i think also faster, but
    the return value of functions could be used instead of course.
    The code also ensures as a side effect that the AC decoder state does not
    become invalid.
    This fixes all known crashes. And outputs nothing in case of an error instead
    of random noise.
    
    Originally committed as revision 12316 to svn://svn.ffmpeg.org/ffmpeg/trunk

diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index 915a2f3..0f8356d 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -156,6 +156,8 @@ typedef struct APEContext {
     uint8_t *data_end;                       ///< frame data end
     const uint8_t *ptr;                      ///< current position in frame data
     const uint8_t *last_ptr;                 ///< position where last 4608-sample block ended
+
+    int error;
 } APEContext;
 
 // TODO: dsputilize
@@ -382,6 +384,13 @@ static inline int range_get_symbol(APEContext * ctx,
 
     cf = range_decode_culshift(ctx, 16);
 
+    if(cf > 65492){
+        symbol= cf - 65535 + 63;
+        range_decode_update(ctx, 1, cf);
+        if(cf > 65535)
+            ctx->error=1;
+        return symbol;
+    }
     /* figure out the symbol inefficiently; a binary search would be much better */
     for (symbol = 0; counts[symbol + 1] <= cf; symbol++);
 
@@ -894,11 +903,19 @@ static int ape_decode_frame(AVCodecContext * avctx,
     nblocks = s->samples;
     blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks);
 
+    s->error=0;
+
     if ((s->channels == 1) || (s->frameflags & APE_FRAMECODE_PSEUDO_STEREO))
         ape_unpack_mono(s, blockstodecode);
     else
         ape_unpack_stereo(s, blockstodecode);
 
+    if(s->error || s->ptr > s->data_end){
+        s->samples=0;
+        av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
+        return -1;
+    }
+
     for (i = 0; i < blockstodecode; i++) {
         *samples++ = s->decoded0[i];
         if(s->channels == 2)

-- 
Libav/FFmpeg packaging



More information about the pkg-multimedia-commits mailing list