summaryrefslogtreecommitdiffstats
path: root/libavcodec/eatgq.c
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2012-03-06 14:18:32 -0800
committerRonald S. Bultje <rsbultje@gmail.com>2012-03-07 09:53:57 -0800
commit1255eed533b4069db7f205601953ca54c0dc42c9 (patch)
treecf87a5c2e4e49464e42a27f2328603c8ada1edb7 /libavcodec/eatgq.c
parentaed9da20afee128a23b0fc6046ca74df74154c5f (diff)
downloadffmpeg-streaming-1255eed533b4069db7f205601953ca54c0dc42c9.zip
ffmpeg-streaming-1255eed533b4069db7f205601953ca54c0dc42c9.tar.gz
tgq: convert to bytestream2 API.
This protects against input buffer overreads. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org
Diffstat (limited to 'libavcodec/eatgq.c')
-rw-r--r--libavcodec/eatgq.c56
1 files changed, 28 insertions, 28 deletions
diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c
index bd6fcf0..b177db5 100644
--- a/libavcodec/eatgq.c
+++ b/libavcodec/eatgq.c
@@ -43,6 +43,7 @@ typedef struct TgqContext {
ScanTable scantable;
int qtable[64];
DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+ GetByteContext gb;
} TgqContext;
static av_cold int tgq_decode_init(AVCodecContext *avctx){
@@ -141,39 +142,36 @@ static void tgq_idct_put_mb_dconly(TgqContext *s, int mb_x, int mb_y, const int8
}
}
-static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x, const uint8_t **bs, const uint8_t *buf_end){
+static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x){
int mode;
int i;
int8_t dc[6];
- mode = bytestream_get_byte(bs);
- if (mode>buf_end-*bs) {
- av_log(s->avctx, AV_LOG_ERROR, "truncated macroblock\n");
- return;
- }
-
+ mode = bytestream2_get_byte(&s->gb);
if (mode>12) {
GetBitContext gb;
- init_get_bits(&gb, *bs, mode*8);
+ init_get_bits(&gb, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode) * 8);
for(i=0; i<6; i++)
tgq_decode_block(s, s->block[i], &gb);
tgq_idct_put_mb(s, s->block, mb_x, mb_y);
+ bytestream2_skip(&s->gb, mode);
}else{
if (mode==3) {
- memset(dc, (*bs)[0], 4);
- dc[4] = (*bs)[1];
- dc[5] = (*bs)[2];
+ memset(dc, bytestream2_get_byte(&s->gb), 4);
+ dc[4] = bytestream2_get_byte(&s->gb);
+ dc[5] = bytestream2_get_byte(&s->gb);
}else if (mode==6) {
- memcpy(dc, *bs, 6);
+ bytestream2_get_buffer(&s->gb, dc, 6);
}else if (mode==12) {
- for(i=0; i<6; i++)
- dc[i] = (*bs)[i*2];
+ for (i = 0; i < 6; i++) {
+ dc[i] = bytestream2_get_byte(&s->gb);
+ bytestream2_skip(&s->gb, 1);
+ }
}else{
av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode);
}
tgq_idct_put_mb_dconly(s, mb_x, mb_y, dc);
}
- *bs += mode;
}
static void tgq_calculate_qtable(TgqContext *s, int quant){
@@ -193,28 +191,30 @@ static int tgq_decode_frame(AVCodecContext *avctx,
AVPacket *avpkt){
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- const uint8_t *buf_start = buf;
- const uint8_t *buf_end = buf + buf_size;
TgqContext *s = avctx->priv_data;
int x,y;
-
int big_endian = AV_RL32(&buf[4]) > 0x000FFFFF;
- buf += 8;
- if(8>buf_end-buf) {
+ if (buf_size < 16) {
av_log(avctx, AV_LOG_WARNING, "truncated header\n");
return -1;
}
- s->width = big_endian ? AV_RB16(&buf[0]) : AV_RL16(&buf[0]);
- s->height = big_endian ? AV_RB16(&buf[2]) : AV_RL16(&buf[2]);
+ bytestream2_init(&s->gb, buf + 8, buf_size - 8);
+ if (big_endian) {
+ s->width = bytestream2_get_be16u(&s->gb);
+ s->height = bytestream2_get_be16u(&s->gb);
+ } else {
+ s->width = bytestream2_get_le16u(&s->gb);
+ s->height = bytestream2_get_le16u(&s->gb);
+ }
if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
avcodec_set_dimensions(s->avctx, s->width, s->height);
if (s->frame.data[0])
avctx->release_buffer(avctx, &s->frame);
}
- tgq_calculate_qtable(s, buf[4]);
- buf += 8;
+ tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb));
+ bytestream2_skip(&s->gb, 3);
if (!s->frame.data[0]) {
s->frame.key_frame = 1;
@@ -226,14 +226,14 @@ static int tgq_decode_frame(AVCodecContext *avctx,
}
}
- for (y=0; y<(avctx->height+15)/16; y++)
- for (x=0; x<(avctx->width+15)/16; x++)
- tgq_decode_mb(s, y, x, &buf, buf_end);
+ for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++)
+ for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++)
+ tgq_decode_mb(s, y, x);
*data_size = sizeof(AVFrame);
*(AVFrame*)data = s->frame;
- return buf-buf_start;
+ return avpkt->size;
}
static av_cold int tgq_decode_end(AVCodecContext *avctx){
OpenPOWER on IntegriCloud