avcodec/cdtoons: Correct several end of data checks in cdtoons_render_sprite()

No testcases, found by code review when debuging issue found by oss-fuzz

Reviewed-by: Paul B Mahol <onemda@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer 2020-02-20 18:49:56 +01:00
parent 553d836d62
commit 4c31db5a32
1 changed files with 14 additions and 10 deletions

View File

@ -82,9 +82,11 @@ static int cdtoons_render_sprite(AVCodecContext *avctx, const uint8_t *data,
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
/* one scanline at a time, size is provided */ /* one scanline at a time, size is provided */
data = next_line; data = next_line;
if (data > end - 2) if (end - data < 2)
return 1; return 1;
line_size = bytestream_get_be16(&data); line_size = bytestream_get_be16(&data);
if (end - data < line_size)
return 1;
next_line = data + line_size; next_line = data + line_size;
if (dst_y + y < 0) if (dst_y + y < 0)
continue; continue;
@ -94,7 +96,7 @@ static int cdtoons_render_sprite(AVCodecContext *avctx, const uint8_t *data,
to_skip = skip; to_skip = skip;
x = 0; x = 0;
while (x < width - skip) { while (x < width - skip) {
int raw, size; int raw, size, step;
uint8_t val; uint8_t val;
if (data >= end) if (data >= end)
@ -108,20 +110,22 @@ static int cdtoons_render_sprite(AVCodecContext *avctx, const uint8_t *data,
if (to_skip >= size) { if (to_skip >= size) {
to_skip -= size; to_skip -= size;
if (raw) { if (raw) {
data += size; step = size;
} else { } else {
data += 1; step = 1;
} }
if (data > next_line) if (next_line - data < step)
return 1; return 1;
data += step;
continue; continue;
} else if (to_skip) { } else if (to_skip) {
size -= to_skip; size -= to_skip;
if (raw) if (raw) {
if (next_line - data < to_skip)
return 1;
data += to_skip; data += to_skip;
}
to_skip = 0; to_skip = 0;
if (data > next_line)
return 1;
} }
if (x + size >= width - skip) if (x + size >= width - skip)
@ -129,10 +133,10 @@ static int cdtoons_render_sprite(AVCodecContext *avctx, const uint8_t *data,
/* either raw data, or a run of a single color */ /* either raw data, or a run of a single color */
if (raw) { if (raw) {
if (next_line - data < size)
return 1;
memcpy(dest + x, data, size); memcpy(dest + x, data, size);
data += size; data += size;
if (data > next_line)
return 1;
} else { } else {
uint8_t color = bytestream_get_byte(&data); uint8_t color = bytestream_get_byte(&data);
/* ignore transparent runs */ /* ignore transparent runs */