Files
ffmpeg/libavcodec
Andreas Rheinhardt 06fef1e9f1 avcodec/put_bits: Make skip_put_bits() less dangerous
Before c63c303a1f (the commit which
introduced a typedef for the type of the buffer of a PutBitContext)
skip_put_bits() was as follows:

static inline void skip_put_bits(PutBitContext *s, int n)
{
    s->bit_left -= n;
    s->buf_ptr  -= 4 * (s->bit_left >> 5);
    s->bit_left &= 31;
}

If s->bit_left was negative after the first subtraction, then the next
line will divide this by 32 with rounding towards -inf and multiply by
four; the result will be negative, of course.

The aforementioned commit changed this to:

static inline void skip_put_bits(PutBitContext *s, int n)
{
    s->bit_left -= n;
    s->buf_ptr  -= sizeof(BitBuf) * ((unsigned)s->bit_left / BUF_BITS);
    s->bit_left &= (BUF_BITS - 1);
}

Casting s->bit_left to unsigned meant that the rounding is still towards
-inf; yet the right side is now always positive (it transformed the
arithmetic shift into a logical shift), so that s->buf_ptr will always
be decremented (by about UINT_MAX / 8 unless n is huge) which leads to
segfaults on further usage and is already undefined pointer arithmetic
before that. This can be reproduced with the mpeg4 encoder with the
AV_CODEC_FLAG2_NO_OUTPUT flag set.

Furthermore, the earlier version as well as the new version share
another bug: s->bit_left will be in the range of 0..(BUF_BITS - 1)
afterwards, although the assumption throughout the other PutBitContext
functions is that it is in the range of 1..BUF_BITS. This might lead to
a shift by BUF_BITS in little-endian mode. This has been fixed, too.
The new version is furthermore able to skip zero bits, too.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-08-08 01:08:47 +02:00
..
2020-02-07 13:36:57 -03:00
2020-08-07 23:04:28 +10:00
2020-08-07 23:04:28 +10:00
2020-02-19 20:48:49 +11:00
2019-06-26 21:25:10 +02:00
2020-06-10 12:36:44 +02:00
2020-08-03 22:45:17 +02:00
2020-07-03 23:28:26 +02:00
2019-08-11 19:13:21 +02:00
2020-03-12 20:26:48 +00:00
2020-03-12 20:26:48 +00:00
2020-05-21 09:31:08 +02:00
2019-11-13 09:08:43 -08:00
2020-07-08 23:09:29 +08:00
2020-02-22 00:15:43 +01:00
2019-05-06 23:58:34 +02:00
2019-12-05 20:20:05 +01:00
2018-12-23 15:30:13 +01:00
2020-03-22 11:55:44 -03:00
2018-12-10 11:19:36 +01:00
2020-07-20 18:41:09 +02:00
2020-06-05 18:14:17 +02:00
2020-06-14 18:20:37 +02:00
2020-06-15 04:22:28 +02:00
2019-08-29 21:04:54 +02:00
2019-01-16 01:29:18 +01:00
2020-07-20 18:41:09 +02:00
2020-07-20 18:41:09 +02:00
2019-06-29 19:22:19 +02:00
2020-08-07 23:04:28 +10:00
2020-04-26 18:38:25 +01:00
2019-08-11 19:13:21 +02:00
2019-12-10 16:09:14 +01:00
2020-01-11 23:31:18 +01:00
2020-05-19 20:09:25 +02:00
2020-05-12 01:00:28 +02:00
2019-09-02 13:46:11 -07:00
2020-05-26 10:52:12 +01:00
2019-03-31 23:35:00 +02:00
2020-05-26 10:52:12 +01:00
2020-05-26 10:52:12 +01:00
2018-12-01 19:41:48 +01:00
2020-06-14 18:20:37 +02:00
2020-06-08 20:45:56 +02:00
2020-05-30 18:02:55 +02:00
2020-07-05 19:59:49 +02:00
2019-10-22 10:51:42 +08:00
2020-02-19 22:37:30 +01:00
2020-04-26 18:38:25 +01:00
2018-12-03 23:34:05 +01:00
2020-01-30 19:57:25 +01:00
2019-08-23 22:24:07 +02:00
2020-04-04 23:26:15 +02:00
2020-05-22 22:23:18 +02:00
2018-11-18 22:59:29 +01:00
2020-08-07 14:01:00 +02:00
2020-07-06 18:23:50 +01:00
2020-07-20 22:31:54 +02:00
2020-08-07 14:01:00 +02:00
2020-01-13 23:26:25 +00:00
2020-07-20 18:41:09 +02:00
2020-08-07 23:04:28 +10:00
2020-01-11 23:31:18 +01:00
2020-04-26 18:38:25 +01:00
2020-08-07 23:04:28 +10:00
2020-04-17 19:33:43 +10:00
2019-06-12 20:06:20 +10:00
2019-10-25 00:22:33 +02:00
2019-08-22 18:35:44 +02:00
2020-04-26 18:38:25 +01:00
2019-09-05 19:45:53 +02:00
2019-05-02 15:36:16 +02:00
2020-04-16 15:05:07 -03:00
2020-03-22 11:55:44 -03:00
2020-05-23 07:07:36 +02:00