Commit 4e0af031 authored by Eli Friedman's avatar Eli Friedman Committed by Robert Swain

Remove flexible array member from Escape 124

Patch by Eli Friedman (eli friedman gmail com)

Originally committed as revision 12660 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 2d1cb025
...@@ -37,7 +37,7 @@ typedef union SuperBlock { ...@@ -37,7 +37,7 @@ typedef union SuperBlock {
typedef struct CodeBook { typedef struct CodeBook {
unsigned depth; unsigned depth;
unsigned size; unsigned size;
MacroBlock blocks[0]; MacroBlock* blocks;
} CodeBook; } CodeBook;
typedef struct Escape124Context { typedef struct Escape124Context {
...@@ -45,7 +45,7 @@ typedef struct Escape124Context { ...@@ -45,7 +45,7 @@ typedef struct Escape124Context {
unsigned num_superblocks; unsigned num_superblocks;
CodeBook* codebooks[3]; CodeBook codebooks[3];
} Escape124Context; } Escape124Context;
static int can_safely_read(GetBitContext* gb, int bits) { static int can_safely_read(GetBitContext* gb, int bits) {
...@@ -75,7 +75,7 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx) ...@@ -75,7 +75,7 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx)
Escape124Context *s = avctx->priv_data; Escape124Context *s = avctx->priv_data;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
av_free(s->codebooks[i]); av_free(s->codebooks[i].blocks);
if (s->frame.data[0]) if (s->frame.data[0])
avctx->release_buffer(avctx, &s->frame); avctx->release_buffer(avctx, &s->frame);
...@@ -83,23 +83,23 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx) ...@@ -83,23 +83,23 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx)
return 0; return 0;
} }
static CodeBook* unpack_codebook(GetBitContext* gb, unsigned depth, static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth,
unsigned size) unsigned size)
{ {
unsigned i, j; unsigned i, j;
CodeBook* cb; CodeBook cb = { 0 };
if (!can_safely_read(gb, size * 34)) if (!can_safely_read(gb, size * 34))
return NULL; return cb;
if (size >= (INT_MAX - sizeof(CodeBook)) / sizeof(MacroBlock)) if (size >= INT_MAX / sizeof(MacroBlock))
return NULL; return cb;
cb = av_malloc(size * sizeof(MacroBlock) + sizeof(CodeBook)); cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1);
if (!cb) if (!cb.blocks)
return NULL; return cb;
cb->depth = depth; cb.depth = depth;
cb->size = size; cb.size = size;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
unsigned mask_bits = get_bits(gb, 4); unsigned mask_bits = get_bits(gb, 4);
unsigned color0 = get_bits(gb, 15); unsigned color0 = get_bits(gb, 15);
...@@ -107,9 +107,9 @@ static CodeBook* unpack_codebook(GetBitContext* gb, unsigned depth, ...@@ -107,9 +107,9 @@ static CodeBook* unpack_codebook(GetBitContext* gb, unsigned depth,
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
if (mask_bits & (1 << j)) if (mask_bits & (1 << j))
cb->blocks[i].pixels[j] = color1; cb.blocks[i].pixels[j] = color1;
else else
cb->blocks[i].pixels[j] = color0; cb.blocks[i].pixels[j] = color0;
} }
} }
return cb; return cb;
...@@ -149,7 +149,7 @@ static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb, ...@@ -149,7 +149,7 @@ static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb,
*codebook_index = transitions[*codebook_index][get_bits1(gb)]; *codebook_index = transitions[*codebook_index][get_bits1(gb)];
} }
depth = s->codebooks[*codebook_index]->depth; depth = s->codebooks[*codebook_index].depth;
// depth = 0 means that this shouldn't read any bits; // depth = 0 means that this shouldn't read any bits;
// in theory, this is the same as get_bits(gb, 0), but // in theory, this is the same as get_bits(gb, 0), but
...@@ -157,15 +157,15 @@ static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb, ...@@ -157,15 +157,15 @@ static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb,
block_index = depth ? get_bits(gb, depth) : 0; block_index = depth ? get_bits(gb, depth) : 0;
if (*codebook_index == 1) { if (*codebook_index == 1) {
block_index += superblock_index << s->codebooks[1]->depth; block_index += superblock_index << s->codebooks[1].depth;
} }
// This condition can occur with invalid bitstreams and // This condition can occur with invalid bitstreams and
// *codebook_index == 2 // *codebook_index == 2
if (block_index >= s->codebooks[*codebook_index]->size) if (block_index >= s->codebooks[*codebook_index].size)
return (MacroBlock) { { 0 } }; return (MacroBlock) { { 0 } };
return s->codebooks[*codebook_index]->blocks[block_index]; return s->codebooks[*codebook_index].blocks[block_index];
} }
static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) { static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) {
...@@ -265,9 +265,9 @@ static int escape124_decode_frame(AVCodecContext *avctx, ...@@ -265,9 +265,9 @@ static int escape124_decode_frame(AVCodecContext *avctx,
cb_size = s->num_superblocks << cb_depth; cb_size = s->num_superblocks << cb_depth;
} }
} }
av_free(s->codebooks[i]); av_free(s->codebooks[i].blocks);
s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size);
if (!s->codebooks[i]) if (!s->codebooks[i].blocks)
return -1; return -1;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment