summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2008-03-25 23:34:00 +0000
committerJustin Ruggles <justin.ruggles@gmail.com>2008-03-25 23:34:00 +0000
commitc33a196716bcc36754b3cc5f4c0d22c27045efd5 (patch)
tree938ab499bb9972329ddb57d7f7d70c624be2d262 /libavcodec
parent26759c44804d220deedac861f1b030381d8393be (diff)
additional protection from segmentation faults and memory access errors by
copying the input buffer to a local context buffer which is large enough to hold the largest possible AC3 frame. Originally committed as revision 12593 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/ac3dec.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index 79a8606dba..cd648cecbb 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -39,6 +39,9 @@
#include "dsputil.h"
#include "random.h"
+/** Maximum possible frame size when the specification limit is ignored */
+#define AC3_MAX_FRAME_SIZE 21695
+
/**
* Table of bin locations for rematrixing bands
* reference: Section 7.5.2 Rematrixing : Frequency Band Definitions
@@ -191,6 +194,7 @@ typedef struct {
GetBitContext gbc; ///< bitstream reader
AVRandomState dith_state; ///< for dither generation
AVCodecContext *avctx; ///< parent context
+ uint8_t input_buffer[AC3_MAX_FRAME_SIZE]; ///< temp buffer to prevent overread
} AC3DecodeContext;
/**
@@ -1133,7 +1137,14 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
int i, blk, ch, err;
/* initialize the GetBitContext with the start of valid AC-3 Frame */
+ if(avctx->error_resilience >= FF_ER_CAREFUL) {
+ /* copy input buffer to decoder context to avoid reading past the end
+ of the buffer, which can be caused by a damaged input stream. */
+ memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_MAX_FRAME_SIZE));
+ init_get_bits(&s->gbc, s->input_buffer, buf_size * 8);
+ } else {
init_get_bits(&s->gbc, buf, buf_size * 8);
+ }
/* parse the syncinfo */
err = ac3_parse_header(s);