[FFmpeg-devel] [PATCH] avformat: add vividas demuxer

Tomas Härdin tjoppen at acc.umu.se
Sun Dec 16 23:03:36 EET 2018


lör 2018-12-15 klockan 20:06 +0100 skrev Paul B Mahol:
> > Signed-off-by: Paul B Mahol <onemda at gmail.com>
> +
> +static void put_v(uint8_t *p, int v)

This should take unsigned

> +{
> +    if (v>>28)
> +        *p++ = ((v>>28)&0x7f)|0x80;
> +    if (v>>21)
> +        *p++ = ((v>>21)&0x7f)|0x80;
> +    if (v>>14)
> +        *p++ = ((v>>14)&0x7f)|0x80;
> +    if (v>>7)
> +        *p++ =  ((v>>7)&0x7f)|0x80;
> +}
> +
> +static unsigned int recover_key(unsigned char sample[4], int expected_size)

this too

> +{
> +    unsigned char plaintext[8] = { 'S', 'B' };
> +
> +    put_v(plaintext+2, expected_size);
> +
> +    return (sample[0]^plaintext[0])|
> +        ((sample[1]^plaintext[1])<<8)|
> +        ((sample[2]^plaintext[2])<<16)|
> +        ((sample[3]^plaintext[3])<<24);
> +}
> +
> +static void xor_block(void *p1, void *p2, int size, int key, int *key_ptr)

here as well

> +{
> +    int *d1 = p1;
> +    int *d2 = p2;
> +    int k = *key_ptr;
> +
> +    size >>= 2;
> +
> +    while (size--) {
> +        *d2 = *d1 ^ k;
> +        k += key;
> +        d1++;
> +        d2++;
> +    }
> +
> +    *key_ptr = k;
> +}
> +
> +static void decode_block(uint8_t *src, uint8_t *dest, int size,
> +                         uint32_t key, uint32_t *key_ptr,
> +                         int align)

and here

> +{
> +    int s = size;
> +    char tmp[4];
> +    int a2;
> +
> +    if (!size)
> +        return;
> +
> +    align &= 3;
> +    a2 = (4 - align) & 3;
> +
> +    if (align) {
> +        uint32_t tmpkey = *key_ptr - key;
> +        memcpy(tmp + align, src, a2);
> +        xor_block(tmp, tmp, 4, key, &tmpkey);
> +        memcpy(dest, tmp + align, a2);
> +        s -= a2;
> +    }
> +
> +    if (s >= 4) {
> +        if (!align)
> +            align = 4;
> +        xor_block(src + a2, dest + a2, s & ~3,
> +                  key, key_ptr);
> +        s &= 3;
> +    }
> +
> +    if (s) {
> +        size -= s;
> +        memcpy(tmp, src + size, s);
> +        xor_block(&tmp, &tmp, 4, key, key_ptr);
> +        memcpy(dest + size, tmp, s);
> +    }
> +}
> +

Becaaaause:

> +static uint32_t get_v(uint8_t *p)
> +{
> +    uint32_t v = 0;
> +
> +    do {
> +        if (v >= UINT_MAX / 128 - *p)
> +            return v;
> +        v <<= 7;
> +        v += *p & 0x7f;
> +    } while (*p++ & 0x80);
> +
> +    return v;

This may return values between INT_MAX+1 and UINT_MAX...

> +}
> +
> +static uint8_t *read_vblock(AVIOContext *src, uint32_t *size,
> +                            uint32_t key, uint32_t *k2, int align)
> +{
> +    uint8_t tmp[4];
> +    uint8_t *buf;
> +    unsigned n;
> +
> +    if (avio_read(src, tmp, 4) != 4)
> +        return NULL;
> +
> +    decode_block(tmp, tmp, 4, key, k2, align);
> +
> +    n = get_v(tmp);
> +    if (!n)
> +        return NULL;
> +
> +    buf = av_malloc(n);
> +    if (!buf)
> +        return NULL;
> +
> +    *size = n;
> +    n -= 4;
> +
> +    memcpy(buf, tmp, 4);
> +
> +    if (avio_read(src, buf + 4, n) == n) {
> +        decode_block(buf + 4, buf + 4, n, key, k2, align + 4);

which get passed in here ^
leading to undefined behavior

> +    } else {
> +        av_free(buf);
> +        buf = NULL;
> +    }
> +
> +    return buf;
> +}
> +
> +static uint8_t *read_sb_block(AVIOContext *src, unsigned *size,
> +                              uint32_t *key, int expected_size)

expected_size should be unsigned too.. And so on, I think you get the
picture

/Tomas



More information about the ffmpeg-devel mailing list