[FFmpeg-cvslog] r12316 - trunk/libavcodec/apedec.c
michael
subversion
Tue Mar 4 22:58:34 CET 2008
Author: michael
Date: Tue Mar 4 22:58:34 2008
New Revision: 12316
Log:
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.
Modified:
trunk/libavcodec/apedec.c
Modified: trunk/libavcodec/apedec.c
==============================================================================
--- trunk/libavcodec/apedec.c (original)
+++ trunk/libavcodec/apedec.c Tue Mar 4 22:58:34 2008
@@ -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(APECo
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(AVCodecConte
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)
More information about the ffmpeg-cvslog
mailing list