summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMark Thompson <sw@jkqxz.net>2017-09-12 22:11:41 +0100
committerMark Thompson <sw@jkqxz.net>2017-09-12 22:11:41 +0100
commit44cde38c8acbef7d5250e6d1b52b1020871e093b (patch)
tree2629beca29d8ded943048da87affda1af7e4a285 /libavcodec
parentb05128f3c953bd66483e697d60a2e7e45ee9cfa0 (diff)
cbs: Always check for bitstream end before reading
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/cbs.c6
-rw-r--r--libavcodec/cbs_h2645.c118
-rw-r--r--libavcodec/cbs_mpeg2.c5
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"