Fixes: out of array access Fixes: 48567/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_EATGQ_fuzzer-6743211456724992
Showing the changes to libavcodec (1 of 1 file). Show all
Unified · Split
| @@ -56,7 +56,7 @@ static av_cold int tgq_decode_init(AVCodecContext *avctx) · 55 unmodified lines | ||
| 56 | 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 | 61 | const uint8_t *scantable = ff_zigzag_direct; |
| 62 | 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 | 64 | for (i = 1; i < 64;) { |
| 65 | 65 | switch (show_bits(gb, 3)) { |
| 66 | 66 | case 4: |
| 67 | + if (i >= 63) | |
| 68 | + return AVERROR_INVALIDDATA; | |
| 67 | 69 | block[scantable[i++]] = 0; |
| 68 | 70 | case 0: |
| 69 | 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 | 75 | case 1: |
| 74 | 76 | skip_bits(gb, 2); |
| 75 | 77 | value = get_bits(gb, 6); |
| 78 | + if (value > 64 - i) | |
| 79 | + return AVERROR_INVALIDDATA; | |
| 76 | 80 | for (j = 0; j < value; j++) |
| 77 | 81 | block[scantable[i++]] = 0; |
| 78 | 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 | 106 | block[0] += 128 << 4; |
| 107 | + return 0; | |
| 103 | 108 | } |
| 104 | 109 | |
| 105 | 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 | 165 | if (ret < 0) |
| 161 | 166 | return ret; |
| 162 | 167 | |
| 163 | − for (i = 0; i < 6; i++) | |
| 164 | − tgq_decode_block(s, s->block[i], &gb); | |
| 168 | + for (i = 0; i < 6; i++) { | |
| 169 | + int ret = tgq_decode_block(s, s->block[i], &gb); | |
| 170 | + if (ret < 0) | |
| 171 | + return ret; | |
| 172 | + } | |
| 165 | 173 | tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); |
| 166 | 174 | bytestream2_skip(gbyte, mode); |
| 167 | 175 | } else { |