[FFmpeg-devel] [PATCH] avcodec: add mvdv video decoder

Tomas Härdin tjoppen at acc.umu.se
Sun Nov 24 13:02:41 EET 2019


sön 2019-11-24 klockan 11:12 +0100 skrev Paul B Mahol:
> +static ptrdiff_t lzss_uncompress(MidiVidContext *s, GetByteContext *gb, uint8_t *dst, int size)
> +{
> +    uint8_t *dst_start = dst;
> +    uint8_t *dst_end = dst + size;
> +
> +    for (;bytestream2_get_bytes_left(gb) > 0;) {

bytestream2_get_bytes_left(gb) >= 3 perhaps?

> +        int op = bytestream2_get_le16(gb);
> +
> +        for (int i = 0; i < 16; i++) {
> +            if (op & 1) {
> +                int s0 = bytestream2_get_byte(gb);
> +                int s1 = bytestream2_get_byte(gb);
> +                int offset = ((s0 & 0xF0) << 4) | s1;
> +                int length = (s0 & 0xF) + 3;
> +
> +                if (dst + length >= dst_end ||

Seems to be dst + length > dst_end should be enough

> +                    dst - offset < dst_start)
> +                    return AVERROR_INVALIDDATA;
> +                for (int j = 0; j < length; j++) {
> +                    dst[j] = dst[j - offset];

This is UB if offset == 0

> +                }
> +                dst += length;
> +            } else {
> +                if (dst >= dst_end)
> +                    return AVERROR_INVALIDDATA;
> +                *dst++ = bytestream2_get_byte(gb);
> +            }
> +            op >>= 1;
> +        }
> +    }
> +
> +    return dst - dst_start;
> +}
> +
> +static int decode_frame(AVCodecContext *avctx, void *data,
> +                        int *got_frame, AVPacket *avpkt)
> +{
> +    MidiVidContext *s = avctx->priv_data;
> +    GetByteContext *gb = &s->gb;
> +    AVFrame *frame = s->frame;
> +    int ret, key, uncompressed;
> +
> +    if (avpkt->size <= 13)
> +        return AVERROR_INVALIDDATA;
> +
> +    bytestream2_init(gb, avpkt->data, avpkt->size);
> +    bytestream2_skip(gb, 8);
> +    uncompressed = bytestream2_get_le32(gb);
> +
> +    if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
> +        return ret;
> +
> +    if (uncompressed) {
> +        ret = decode_mvdv(s, avctx, frame);
> +    } else {
> +        av_fast_padded_malloc(&s->uncompressed, &s->uncompressed_size, 16LL * (avpkt->size - 12));

Can avpkt->size be > LLONG_MAX/16+12 here?

/Tomas



More information about the ffmpeg-devel mailing list