diff options
-rw-r--r-- | libavcodec/xxan.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c index 86b4195ce4..dd5447940b 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -162,7 +162,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) int i, j; const uint8_t *src, *src_end; const uint8_t *table; - int mode, offset, dec_size; + int mode, offset, dec_size, table_size; if (!chroma_off) return 0; @@ -171,9 +171,11 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) return -1; } bytestream2_seek(&s->gb, chroma_off + 4, SEEK_SET); - mode = bytestream2_get_le16(&s->gb); - table = s->gb.buffer; - offset = bytestream2_get_le16(&s->gb) * 2; + mode = bytestream2_get_le16(&s->gb); + table = s->gb.buffer; + table_size = bytestream2_get_le16(&s->gb); + offset = table_size * 2; + table_size += 1; if (offset >= bytestream2_get_bytes_left(&s->gb)) { av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n"); @@ -196,7 +198,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) for (j = 0; j < avctx->height >> 1; j++) { for (i = 0; i < avctx->width >> 1; i++) { val = *src++; - if (val) { + if (val && val < table_size) { val = AV_RL16(table + (val << 1)); uval = (val >> 3) & 0xF8; vval = (val >> 8) & 0xF8; @@ -216,7 +218,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) for (j = 0; j < avctx->height >> 2; j++) { for (i = 0; i < avctx->width >> 1; i += 2) { val = *src++; - if (val) { + if (val && val < table_size) { val = AV_RL16(table + (val << 1)); uval = (val >> 3) & 0xF8; vval = (val >> 8) & 0xF8; |