Fixes: out of array access Fixes: 48567/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_EATGQ_fuzzer-6743211456724992
Unified · Split
| @@ -56,7 +56,7 @@ static av_cold int tgq_decode_init(AVCodecContext *avctx) · 55 unmodified lines | |||
| 56 | return 0; | 56 | return 0; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb) | 59 | static int tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb) |
| 60 | { | 60 | { |
| 61 | const uint8_t *scantable = ff_zigzag_direct; | 61 | const uint8_t *scantable = ff_zigzag_direct; |
| 62 | int i, j, value; | 62 | int i, j, value; |
| @@ -64,6 +64,8 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb · 1 unmodified line | |||
| 64 | for (i = 1; i < 64;) { | 64 | for (i = 1; i < 64;) { |
| 65 | switch (show_bits(gb, 3)) { | 65 | switch (show_bits(gb, 3)) { |
| 66 | case 4: | 66 | case 4: |
| 67 | if (i >= 63) | ||
| 68 | return AVERROR_INVALIDDATA; | ||
| 67 | block[scantable[i++]] = 0; | 69 | block[scantable[i++]] = 0; |
| 68 | case 0: | 70 | case 0: |
| 69 | block[scantable[i++]] = 0; | 71 | block[scantable[i++]] = 0; |
| @@ -73,6 +75,8 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb · 3 unmodified lines | |||
| 73 | case 1: | 75 | case 1: |
| 74 | skip_bits(gb, 2); | 76 | skip_bits(gb, 2); |
| 75 | value = get_bits(gb, 6); | 77 | value = get_bits(gb, 6); |
| 78 | if (value > 64 - i) | ||
| 79 | return AVERROR_INVALIDDATA; | ||
| 76 | for (j = 0; j < value; j++) | 80 | for (j = 0; j < value; j++) |
| 77 | block[scantable[i++]] = 0; | 81 | block[scantable[i++]] = 0; |
| 78 | break; | 82 | break; |
| @@ -100,6 +104,7 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb · 21 unmodified lines | |||
| 100 | } | 104 | } |
| 101 | } | 105 | } |
| 102 | block[0] += 128 << 4; | 106 | block[0] += 128 << 4; |
| 107 | return 0; | ||
| 103 | } | 108 | } |
| 104 | 109 | ||
| 105 | static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame, | 110 | static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame, |
| @@ -160,8 +165,11 @@ static int tgq_decode_mb(TgqContext *s, GetByteContext *gbyte, · 54 unmodified lines | |||
| 160 | if (ret < 0) | 165 | if (ret < 0) |
| 161 | return ret; | 166 | return ret; |
| 162 | 167 | ||
| 163 | for (i = 0; i < 6; i++) | 168 | for (i = 0; i < 6; i++) { |
| 164 | tgq_decode_block(s, s->block[i], &gb); | 169 | int ret = tgq_decode_block(s, s->block[i], &gb); |
| 170 | if (ret < 0) | ||
| 171 | return ret; | ||
| 172 | } | ||
| 165 | tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); | 173 | tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); |
| 166 | bytestream2_skip(gbyte, mode); | 174 | bytestream2_skip(gbyte, mode); |
| 167 | } else { | 175 | } else { |