[FFmpeg-cvslog] cbs: Always check for bitstream end before reading

Mark Thompson git at videolan.org
Sat Nov 11 19:07:49 EET 2017


ffmpeg | branch: master | Mark Thompson <sw at jkqxz.net> | Tue Sep 12 22:11:41 2017 +0100| [44cde38c8acbef7d5250e6d1b52b1020871e093b] | committer: Mark Thompson

cbs: Always check for bitstream end before reading

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=44cde38c8acbef7d5250e6d1b52b1020871e093b
---

 libavcodec/cbs.c       |   6 +++
 libavcodec/cbs_h2645.c | 118 ++++++++++++++++++++++++-------------------------
 libavcodec/cbs_mpeg2.c |   5 ++-
 3 files changed, 67 insertions(+), 62 deletions(-)

diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c
index 10943164da..7440914939 100644
--- a/libavcodec/cbs.c
+++ b/libavcodec/cbs.c
@@ -313,6 +313,12 @@ int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, BitstreamContext *bc,
 
     av_assert0(width <= 32);
 
+    if (bitstream_bits_left(bc) < width) {
+        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at "
+               "%s: bitstream ended.\n", name);
+        return AVERROR_INVALIDDATA;
+    }
+
     if (ctx->trace_enable)
         position = bitstream_tell(bc);
 
diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
index 4d8ba99b35..c8a13f1679 100644
--- a/libavcodec/cbs_h2645.c
+++ b/libavcodec/cbs_h2645.c
@@ -36,40 +36,39 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc,
                               uint32_t range_min, uint32_t range_max)
 {
     uint32_t value;
-    int position;
+    int position, i, j;
+    unsigned int k;
+    char bits[65];
 
-    if (ctx->trace_enable) {
-        char bits[65];
-        unsigned int k;
-        int i, j;
+    position = bitstream_tell(bc);
 
-        position = bitstream_tell(bc);
-
-        for (i = 0; i < 32; i++) {
-            k = bitstream_read_bit(bc);
-            bits[i] = k ? '1' : '0';
-            if (k)
-                break;
-        }
-        if (i >= 32) {
-            av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid ue-golomb "
-                   "code found while reading %s: "
-                   "more than 31 zeroes.\n", name);
+    for (i = 0; i < 32; i++) {
+        if (bitstream_bits_left(bc) < i + 1) {
+            av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid ue-golomb code at "
+                   "%s: bitstream ended.\n", name);
             return AVERROR_INVALIDDATA;
         }
-        value = 1;
-        for (j = 0; j < i; j++) {
-            k = bitstream_read_bit(bc);
-            bits[i + j + 1] = k ? '1' : '0';
-            value = value << 1 | k;
-        }
-        bits[i + j + 1] = 0;
-        --value;
+        k = bitstream_read_bit(bc);
+        bits[i] = k ? '1' : '0';
+        if (k)
+            break;
+    }
+    if (i >= 32) {
+        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid ue-golomb code at "
+               "%s: more than 31 zeroes.\n", name);
+        return AVERROR_INVALIDDATA;
+    }
+    value = 1;
+    for (j = 0; j < i; j++) {
+        k = bitstream_read_bit(bc);
+        bits[i + j + 1] = k ? '1' : '0';
+        value = value << 1 | k;
+    }
+    bits[i + j + 1] = 0;
+    --value;
 
+    if (ctx->trace_enable)
         ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
-    } else {
-        value = get_ue_golomb_long(bc);
-    }
 
     if (value < range_min || value > range_max) {
         av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
@@ -87,44 +86,43 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc,
                               int32_t range_min, int32_t range_max)
 {
     int32_t value;
-    int position;
+    int position, i, j;
+    unsigned int k;
+    uint32_t v;
+    char bits[65];
 
-    if (ctx->trace_enable) {
-        char bits[65];
-        uint32_t v;
-        unsigned int k;
-        int i, j;
-
-        position = bitstream_tell(bc);
+    position = bitstream_tell(bc);
 
-        for (i = 0; i < 32; i++) {
-            k = bitstream_read_bit(bc);
-            bits[i] = k ? '1' : '0';
-            if (k)
-                break;
-        }
-        if (i >= 32) {
-            av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb "
-                   "code found while reading %s: "
-                   "more than 31 zeroes.\n", name);
+    for (i = 0; i < 32; i++) {
+        if (bitstream_bits_left(bc) < i + 1) {
+            av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb code at "
+                   "%s: bitstream ended.\n", name);
             return AVERROR_INVALIDDATA;
         }
-        v = 1;
-        for (j = 0; j < i; j++) {
-            k = bitstream_read_bit(bc);
-            bits[i + j + 1] = k ? '1' : '0';
-            v = v << 1 | k;
-        }
-        bits[i + j + 1] = 0;
-        if (v & 1)
-            value = -(int32_t)(v / 2);
-        else
-            value = v / 2;
+        k = bitstream_read_bit(bc);
+        bits[i] = k ? '1' : '0';
+        if (k)
+            break;
+    }
+    if (i >= 32) {
+        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb code at "
+               "%s: more than 31 zeroes.\n", name);
+        return AVERROR_INVALIDDATA;
+    }
+    v = 1;
+    for (j = 0; j < i; j++) {
+        k = bitstream_read_bit(bc);
+        bits[i + j + 1] = k ? '1' : '0';
+        v = v << 1 | k;
+    }
+    bits[i + j + 1] = 0;
+    if (v & 1)
+        value = -(int32_t)(v / 2);
+    else
+        value = v / 2;
 
+    if (ctx->trace_enable)
         ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
-    } else {
-        value = get_se_golomb_long(bc);
-    }
 
     if (value < range_min || value > range_max) {
         av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c
index fede3ff471..cbee42e905 100644
--- a/libavcodec/cbs_mpeg2.c
+++ b/libavcodec/cbs_mpeg2.c
@@ -58,8 +58,9 @@
         CHECK(ff_cbs_read_unsigned(ctx, rw, 1, "marker_bit", &one, 1, 1)); \
     } while (0)
 
-#define nextbits(width, compare, var) (var = bitstream_peek(rw, width), \
-                                       var == (compare))
+#define nextbits(width, compare, var) \
+    (bitstream_bits_left(rw) >= width && \
+     (var = bitstream_peek(rw, width)) == (compare))
 
 #include "cbs_mpeg2_syntax_template.c"
 



More information about the ffmpeg-cvslog mailing list