[FFmpeg-devel] [PATCH V4] lavc/golomb: Fix UE golomb overwrite issue.

Jun Zhao mypopydev at gmail.com
Fri Jun 9 05:34:19 EEST 2017


V4: Fix rang check error in assert base on Mark's review
V3: Clean the code logic base on Michael's review.
V2: Add set_ue_golomb_long() to support 32bits UE golomb and update the unit test.
-------------- next part --------------
From fa3f59e5fcb2cddcc44b0e895bfa02caa491fee5 Mon Sep 17 00:00:00 2001
From: Jun Zhao <jun.zhao at intel.com>
Date: Fri, 2 Jun 2017 15:05:49 +0800
Subject: [PATCH V4] lavc/golomb: Fix UE golomb overwrite issue.

put_bits just support write up to 31 bits, when write 32 bit in
put_bits, it's will overwrite the bit buffer, because the default
assert level is 0, the av_assert2(n <= 31 && value < (1U << n))
in put_bits can not be trigger runtime. Add set_ue_golomb_long()
to support 32bits UE golomb.

Signed-off-by: Jun Zhao <jun.zhao at intel.com>
---
 libavcodec/golomb.h       | 17 ++++++++++++++++-
 libavcodec/put_bits.h     | 35 +++++++++++++++++++++++++++++++++++
 libavcodec/tests/golomb.c | 19 +++++++++++++++++++
 3 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
index 0833aff468..52bb88daa7 100644
--- a/libavcodec/golomb.h
+++ b/libavcodec/golomb.h
@@ -458,7 +458,7 @@ static inline int get_te(GetBitContext *s, int r, char *file, const char *func,
 #endif /* TRACE */
 
 /**
- * write unsigned exp golomb code.
+ * write unsigned exp golomb code. 2^16-2 at most.
  */
 static inline void set_ue_golomb(PutBitContext *pb, int i)
 {
@@ -473,6 +473,21 @@ static inline void set_ue_golomb(PutBitContext *pb, int i)
 }
 
 /**
+ * write unsigned exp golomb code. 2^32-2 at most.
+ */
+static inline void set_ue_golomb_long(PutBitContext *pb, uint32_t i)
+{
+    av_assert2(i <= (UINT32_MAX - 1));
+
+    if (i < 256)
+        put_bits(pb, ff_ue_golomb_len[i], i + 1);
+    else {
+        int e = av_log2(i + 1);
+        put_bits64(pb, 2 * e + 1, i + 1);
+    }
+}
+
+/**
  * write truncated unsigned exp golomb code.
  */
 static inline void set_te_golomb(PutBitContext *pb, int i, int range)
diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h
index 68ed391195..132d07558e 100644
--- a/libavcodec/put_bits.h
+++ b/libavcodec/put_bits.h
@@ -221,6 +221,41 @@ static void av_unused put_bits32(PutBitContext *s, uint32_t value)
 }
 
 /**
+ * Write up to 64 bits into a bitstream.
+ */
+static inline void put_bits64(PutBitContext *s, int n, uint64_t value)
+{
+    av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n)));
+
+    if (n < 32)
+        put_bits(s, n, value);
+    else if (n == 32)
+        put_bits32(s, value);
+    else if (n < 64) {
+        uint32_t lo = value & 0xffffffff;
+        uint32_t hi = value >> 32;
+#ifdef BITSTREAM_WRITER_LE
+        put_bits32(s, lo);
+        put_bits(s, n - 32, hi);
+#else
+        put_bits(s, n - 32, hi);
+        put_bits32(s, lo);
+#endif
+    } else {
+        uint32_t lo = value & 0xffffffff;
+        uint32_t hi = value >> 32;
+#ifdef BITSTREAM_WRITER_LE
+        put_bits32(s, lo);
+        put_bits32(s, hi);
+#else
+        put_bits32(s, hi);
+        put_bits32(s, lo);
+#endif
+
+    }
+}
+
+/**
  * Return the pointer to the byte where the bitstream writer will put
  * the next bit.
  */
diff --git a/libavcodec/tests/golomb.c b/libavcodec/tests/golomb.c
index 965367b7be..85b8a9390b 100644
--- a/libavcodec/tests/golomb.c
+++ b/libavcodec/tests/golomb.c
@@ -21,6 +21,7 @@
 #include <stdint.h>
 #include <stdio.h>
 
+#include "libavutil/internal.h"
 #include "libavutil/mem.h"
 
 #include "libavcodec/get_bits.h"
@@ -76,6 +77,24 @@ int main(void)
         }
     }
 
+#define EXTEND_L(i) ((i) << 4 | (i) & 15)
+    init_put_bits(&pb, temp, SIZE);
+    for (i = 0; i < COUNT; i++)
+        set_ue_golomb_long(&pb, EXTEND_L(i));
+    flush_put_bits(&pb);
+
+    init_get_bits(&gb, temp, 8 * SIZE);
+    for (i = 0; i < COUNT; i++) {
+        int j, s = show_bits_long(&gb, 32);
+
+        j = get_ue_golomb_long(&gb);
+        if (j != EXTEND_L(i)) {
+            fprintf(stderr, "get_ue_golomb_long: expected %d, got %d. "
+                    "bits: %8x\n", EXTEND_L(i), j, s);
+            ret = 1;
+        }
+    }
+
     init_put_bits(&pb, temp, SIZE);
     for (i = 0; i < COUNT; i++)
         set_se_golomb(&pb, i - COUNT / 2);
-- 
2.11.0



More information about the ffmpeg-devel mailing list