avcodec/c93: Fix segfault when using negative linesizes

c93.c used an int for the stride and an unsigned for the current
linenumber. This does not work when using negative linesizes.
So use ptrdiff_t for stride and int for linenumber.

This fixes the cyberia-c93 FATE test when using negative linesizes.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
pull/388/head
Andreas Rheinhardt 2 years ago
parent ce4713ea73
commit fced3a17db
  1. 15
      libavcodec/c93.c

@ -130,7 +130,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
AVFrame * const oldpic = c93->pictures[c93->currentpic^1]; AVFrame * const oldpic = c93->pictures[c93->currentpic^1];
GetByteContext gb; GetByteContext gb;
uint8_t *out; uint8_t *out;
int stride, ret, i, x, y, b, bt = 0; int ret, i, x, y, b, bt = 0;
ptrdiff_t stride;
if ((ret = ff_set_dimensions(avctx, WIDTH, HEIGHT)) < 0) if ((ret = ff_set_dimensions(avctx, WIDTH, HEIGHT)) < 0)
return ret; return ret;
@ -156,7 +157,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
out = newpic->data[0] + y * stride; out = newpic->data[0] + y * stride;
for (x = 0; x < WIDTH; x += 8) { for (x = 0; x < WIDTH; x += 8) {
uint8_t *copy_from = oldpic->data[0]; uint8_t *copy_from = oldpic->data[0];
unsigned int offset, j;
uint8_t cols[4], grps[4]; uint8_t cols[4], grps[4];
C93BlockType block_type; C93BlockType block_type;
@ -165,16 +165,17 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
block_type= bt & 0x0F; block_type= bt & 0x0F;
switch (block_type) { switch (block_type) {
case C93_8X8_FROM_PREV: case C93_8X8_FROM_PREV: {
offset = bytestream2_get_le16(&gb); int offset = bytestream2_get_le16(&gb);
if ((ret = copy_block(avctx, out, copy_from, offset, 8, stride)) < 0) if ((ret = copy_block(avctx, out, copy_from, offset, 8, stride)) < 0)
return ret; return ret;
break; break;
}
case C93_4X4_FROM_CURR: case C93_4X4_FROM_CURR:
copy_from = newpic->data[0]; copy_from = newpic->data[0];
case C93_4X4_FROM_PREV: case C93_4X4_FROM_PREV:
for (j = 0; j < 8; j += 4) { for (int j = 0; j < 8; j += 4) {
for (i = 0; i < 8; i += 4) { for (i = 0; i < 8; i += 4) {
int offset = bytestream2_get_le16(&gb); int offset = bytestream2_get_le16(&gb);
int from_x = offset % WIDTH; int from_x = offset % WIDTH;
@ -203,7 +204,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
case C93_4X4_2COLOR: case C93_4X4_2COLOR:
case C93_4X4_4COLOR: case C93_4X4_4COLOR:
case C93_4X4_4COLOR_GRP: case C93_4X4_4COLOR_GRP:
for (j = 0; j < 8; j += 4) { for (int j = 0; j < 8; j += 4) {
for (i = 0; i < 8; i += 4) { for (i = 0; i < 8; i += 4) {
if (block_type == C93_4X4_2COLOR) { if (block_type == C93_4X4_2COLOR) {
bytestream2_get_buffer(&gb, cols, 2); bytestream2_get_buffer(&gb, cols, 2);
@ -226,7 +227,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
break; break;
case C93_8X8_INTRA: case C93_8X8_INTRA:
for (j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
bytestream2_get_buffer(&gb, out + j*stride, 8); bytestream2_get_buffer(&gb, out + j*stride, 8);
break; break;

Loading…
Cancel
Save