]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/put_bits: Don't set size_in_bits, fix overflow
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Thu, 25 Mar 2021 13:17:10 +0000 (14:17 +0100)
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>
Tue, 30 Mar 2021 10:36:32 +0000 (12:36 +0200)
A PutBitContext has a field called size_in_bits which is set to the
context's bitsize init_put_bits(); but it isn't used at all (the PutBits
API uses pointers directly and not bit indexes), so remove it (due to
ABI concerns the actual element is only removed at the next bump).

Furthermore, the multiplication inherent in setting this field can lead
to undefined integer overflows. This is particularly true for FFV1,
which uses a very big worst-case buffer (37*4*width*height; even
ordinary 1080p triggers an overflow). Ticket #8350 is about this
overflow which this commit fixes.

This means that the effective range of the PutBits API is no longer
restricted by the /8 as long as one isn't using put_bits_(count|left).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
libavcodec/put_bits.h

index e8bc86a82cada985e4312c89e73445555e671a59..15c2650724a3a4ad9a99ef9f6d79dc0b53721775 100644 (file)
@@ -52,7 +52,9 @@ typedef struct PutBitContext {
     BitBuf bit_buf;
     int bit_left;
     uint8_t *buf, *buf_ptr, *buf_end;
+#if LIBAVCODEC_VERSION_MAJOR < 59
     int size_in_bits;
+#endif
 } PutBitContext;
 
 /**
@@ -69,7 +71,6 @@ static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
         buffer      = NULL;
     }
 
-    s->size_in_bits = 8 * buffer_size;
     s->buf          = buffer;
     s->buf_end      = s->buf + buffer_size;
     s->buf_ptr      = s->buf;
@@ -120,7 +121,6 @@ static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer,
     s->buf_end = buffer + buffer_size;
     s->buf_ptr = buffer + (s->buf_ptr - s->buf);
     s->buf     = buffer;
-    s->size_in_bits = 8 * buffer_size;
 }
 
 /**
@@ -414,7 +414,6 @@ static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
 {
     av_assert0(size <= INT_MAX/8 - BUF_BITS);
     s->buf_end = s->buf + size;
-    s->size_in_bits = 8*size;
 }
 
 /**