History

lavc/bitstream: avoid UB in bits_{read,peek}_signed(0)

bits_*_signed(0) will currently invoke an undefined shift by 8 * sizeof(int). Add bits_*_signed_nz() that only works for n>0, analogous to bits_read_nz(). Add an explicit check for n=0 in bits_*_signed().

Anton Khirnov committed 3 years ago

Commit 0b333101 parent bf23d533 files · +39 −3Browse files

Unified · Split

3 files
  1. libavcodec/bitstream.h +4 −0
  2. libavcodec/bitstream_template.h +34 −2
  3. libavcodec/get_bits.h +1 −1
libavcodec/bitstream.h+4−0
@@ -89,9 +89,11 @@ · 88 unmodified lines
89# define bits_read_63 bits_read_63_le89# define bits_read_63 bits_read_63_le
90# define bits_read_64 bits_read_64_le90# define bits_read_64 bits_read_64_le
91# define bits_read_signed bits_read_signed_le91# define bits_read_signed bits_read_signed_le
92# define bits_read_signed_nz bits_read_signed_nz_le
92# define bits_peek_nz bits_peek_nz_le93# define bits_peek_nz bits_peek_nz_le
93# define bits_peek bits_peek_le94# define bits_peek bits_peek_le
94# define bits_peek_signed bits_peek_signed_le95# define bits_peek_signed bits_peek_signed_le
96# define bits_peek_signed_nz bits_peek_signed_nz_le
95# define bits_skip bits_skip_le97# define bits_skip bits_skip_le
96# define bits_seek bits_seek_le98# define bits_seek bits_seek_le
97# define bits_align bits_align_le99# define bits_align bits_align_le
@@ -115,9 +117,11 @@ · 17 unmodified lines
115# define bits_read_63 bits_read_63_be117# define bits_read_63 bits_read_63_be
116# define bits_read_64 bits_read_64_be118# define bits_read_64 bits_read_64_be
117# define bits_read_signed bits_read_signed_be119# define bits_read_signed bits_read_signed_be
120# define bits_read_signed_nz bits_read_signed_nz_be
118# define bits_peek_nz bits_peek_nz_be121# define bits_peek_nz bits_peek_nz_be
119# define bits_peek bits_peek_be122# define bits_peek bits_peek_be
120# define bits_peek_signed bits_peek_signed_be123# define bits_peek_signed bits_peek_signed_be
124# define bits_peek_signed_nz bits_peek_signed_nz_be
121# define bits_skip bits_skip_be125# define bits_skip bits_skip_be
122# define bits_seek bits_seek_be126# define bits_seek bits_seek_be
123# define bits_align bits_align_be127# define bits_align bits_align_be
libavcodec/bitstream_template.h+34−2
@@ -290,13 +290,29 @@ static inline uint64_t BS_FUNC(read_64)(BSCTX *bc, unsigned int n) · 289 unmodified lines
290 return BS_FUNC(read_63)(bc, n);290 return BS_FUNC(read_63)(bc, n);
291}291}
292 292
293/**
294 * Return n bits from the buffer as a signed integer, n has to be in the 1-32
295 * range. May be faster than bits_read_signed() when n is not a compile-time
296 * constant and is known to be non-zero;
297 */
298static inline int32_t BS_FUNC(read_signed_nz)(BSCTX *bc, unsigned int n)
299{
300 av_assert2(n > 0 && n <= 32);
301 return sign_extend(BS_FUNC(read_nz)(bc, n), n);
302}
303
293/**304/**
294 * Return n bits from the buffer as a signed integer.305 * Return n bits from the buffer as a signed integer.
295 * n has to be in the 0-32 range.306 * n has to be in the 0-32 range.
296 */307 */
297static inline int32_t BS_FUNC(read_signed)(BSCTX *bc, unsigned int n)308static inline int32_t BS_FUNC(read_signed)(BSCTX *bc, unsigned int n)
298{309{
299 return sign_extend(BS_FUNC(read)(bc, n), n);310 av_assert2(n <= 32);
311
312 if (!n)
313 return 0;
314
315 return BS_FUNC(read_signed_nz)(bc, n);
300}316}
301 317
302/**318/**
@@ -327,6 +343,17 @@ static inline uint32_t BS_FUNC(peek)(BSCTX *bc, unsigned int n) · 24 unmodified lines
327 return BS_FUNC(peek_nz)(bc, n);343 return BS_FUNC(peek_nz)(bc, n);
328}344}
329 345
346/**
347 * Return n bits from the buffer as a signed integer, do not change the buffer
348 * state. n has to be in the 1-32 range. May be faster than bits_peek_signed()
349 * when n is not a compile-time constant and is known to be non-zero;
350 */
351static inline int BS_FUNC(peek_signed_nz)(BSCTX *bc, unsigned int n)
352{
353 av_assert2(n > 0 && n <= 32);
354 return sign_extend(BS_FUNC(peek_nz)(bc, n), n);
355}
356
330/**357/**
331 * Return n bits from the buffer as a signed integer,358 * Return n bits from the buffer as a signed integer,
332 * do not change the buffer state.359 * do not change the buffer state.
@@ -334,7 +361,12 @@ static inline uint32_t BS_FUNC(peek)(BSCTX *bc, unsigned int n) · 1 unmodified line
334 */361 */
335static inline int BS_FUNC(peek_signed)(BSCTX *bc, unsigned int n)362static inline int BS_FUNC(peek_signed)(BSCTX *bc, unsigned int n)
336{363{
337 return sign_extend(BS_FUNC(peek)(bc, n), n);364 av_assert2(n <= 32);
365
366 if (!n)
367 return 0;
368
369 return BS_FUNC(peek_signed_nz)(bc, n);
338}370}
339 371
340/**372/**
libavcodec/get_bits.h+1−1
@@ -85,7 +85,7 @@ typedef BitstreamContext GetBitContext; · 84 unmodified lines
85#define get_bits1 bits_read_bit85#define get_bits1 bits_read_bit
86#define get_bits64 bits_read_6486#define get_bits64 bits_read_64
87#define get_xbits bits_read_xbits87#define get_xbits bits_read_xbits
88#define get_sbits bits_read_signed88#define get_sbits bits_read_signed_nz
89#define get_sbits_long bits_read_signed89#define get_sbits_long bits_read_signed
90#define show_bits bits_peek90#define show_bits bits_peek
91#define show_bits_long bits_peek91#define show_bits_long bits_peek

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t