Commit 44cde38c authored by Mark Thompson's avatar Mark Thompson

cbs: Always check for bitstream end before reading

parent b05128f3
...@@ -313,6 +313,12 @@ int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, BitstreamContext *bc, ...@@ -313,6 +313,12 @@ int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, BitstreamContext *bc,
av_assert0(width <= 32); 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) if (ctx->trace_enable)
position = bitstream_tell(bc); position = bitstream_tell(bc);
......
...@@ -36,25 +36,26 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, ...@@ -36,25 +36,26 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc,
uint32_t range_min, uint32_t range_max) uint32_t range_min, uint32_t range_max)
{ {
uint32_t value; uint32_t value;
int position; int position, i, j;
if (ctx->trace_enable) {
char bits[65];
unsigned int k; unsigned int k;
int i, j; char bits[65];
position = bitstream_tell(bc); position = bitstream_tell(bc);
for (i = 0; i < 32; i++) { 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;
}
k = bitstream_read_bit(bc); k = bitstream_read_bit(bc);
bits[i] = k ? '1' : '0'; bits[i] = k ? '1' : '0';
if (k) if (k)
break; break;
} }
if (i >= 32) { if (i >= 32) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid ue-golomb " av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid ue-golomb code at "
"code found while reading %s: " "%s: more than 31 zeroes.\n", name);
"more than 31 zeroes.\n", name);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
value = 1; value = 1;
...@@ -66,10 +67,8 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, ...@@ -66,10 +67,8 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc,
bits[i + j + 1] = 0; bits[i + j + 1] = 0;
--value; --value;
if (ctx->trace_enable)
ff_cbs_trace_syntax_element(ctx, position, name, bits, value); ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
} else {
value = get_ue_golomb_long(bc);
}
if (value < range_min || value > range_max) { if (value < range_min || value > range_max) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
...@@ -87,26 +86,27 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, ...@@ -87,26 +86,27 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc,
int32_t range_min, int32_t range_max) int32_t range_min, int32_t range_max)
{ {
int32_t value; int32_t value;
int position; int position, i, j;
if (ctx->trace_enable) {
char bits[65];
uint32_t v;
unsigned int k; unsigned int k;
int i, j; uint32_t v;
char bits[65];
position = bitstream_tell(bc); position = bitstream_tell(bc);
for (i = 0; i < 32; i++) { 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;
}
k = bitstream_read_bit(bc); k = bitstream_read_bit(bc);
bits[i] = k ? '1' : '0'; bits[i] = k ? '1' : '0';
if (k) if (k)
break; break;
} }
if (i >= 32) { if (i >= 32) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb " av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb code at "
"code found while reading %s: " "%s: more than 31 zeroes.\n", name);
"more than 31 zeroes.\n", name);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
v = 1; v = 1;
...@@ -121,10 +121,8 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, ...@@ -121,10 +121,8 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc,
else else
value = v / 2; value = v / 2;
if (ctx->trace_enable)
ff_cbs_trace_syntax_element(ctx, position, name, bits, value); ff_cbs_trace_syntax_element(ctx, position, name, bits, value);
} else {
value = get_se_golomb_long(bc);
}
if (value < range_min || value > range_max) { if (value < range_min || value > range_max) {
av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: "
......
...@@ -58,8 +58,9 @@ ...@@ -58,8 +58,9 @@
CHECK(ff_cbs_read_unsigned(ctx, rw, 1, "marker_bit", &one, 1, 1)); \ CHECK(ff_cbs_read_unsigned(ctx, rw, 1, "marker_bit", &one, 1, 1)); \
} while (0) } while (0)
#define nextbits(width, compare, var) (var = bitstream_peek(rw, width), \ #define nextbits(width, compare, var) \
var == (compare)) (bitstream_bits_left(rw) >= width && \
(var = bitstream_peek(rw, width)) == (compare))
#include "cbs_mpeg2_syntax_template.c" #include "cbs_mpeg2_syntax_template.c"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment