summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfoo86 <foobaz86@gmail.com>2017-07-22 17:19:25 +0300
committerfoo86 <foobaz86@gmail.com>2017-07-26 21:23:07 +0300
commit5e715b583dab85735660b15a8d217a69164675fe (patch)
tree18a71229e85d9060e41a9cba8320dd5c8603561d
parent0689cc2475557339a00240d05b7fc4fcb70e21cd (diff)
avcodec/dolby_e: fix potentially undefined pointer arithmetic
Avoid undefined behavior in skip_input() by checking that enough data is available before incrementing input pointer. Check return values of parse_key() and skip_input() and exit early with error if there is not enough data.
-rw-r--r--libavcodec/dolby_e.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c
index f811db4d8e..91a00ce878 100644
--- a/libavcodec/dolby_e.c
+++ b/libavcodec/dolby_e.c
@@ -28,21 +28,28 @@
#include "dolby_e.h"
#include "fft.h"
-static void skip_input(DBEContext *s, int nb_words)
+static int skip_input(DBEContext *s, int nb_words)
{
+ if (nb_words > s->input_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "Packet too short\n");
+ return AVERROR_INVALIDDATA;
+ }
+
s->input += nb_words * s->word_bytes;
s->input_size -= nb_words;
+ return 0;
}
static int parse_key(DBEContext *s)
{
- int key = 0;
-
- if (s->key_present && s->input_size > 0)
- key = AV_RB24(s->input) >> 24 - s->word_bits;
-
- skip_input(s, s->key_present);
- return key;
+ if (s->key_present) {
+ uint8_t *key = s->input;
+ int ret = skip_input(s, 1);
+ if (ret < 0)
+ return ret;
+ return AV_RB24(key) >> 24 - s->word_bits;
+ }
+ return 0;
}
static int convert_input(DBEContext *s, int nb_words, int key)
@@ -83,8 +90,10 @@ static int convert_input(DBEContext *s, int nb_words, int key)
static int parse_metadata(DBEContext *s)
{
- int i, ret, key = parse_key(s), mtd_size;
+ int i, ret, key, mtd_size;
+ if ((key = parse_key(s)) < 0)
+ return key;
if ((ret = convert_input(s, 1, key)) < 0)
return ret;
@@ -135,14 +144,13 @@ static int parse_metadata(DBEContext *s)
return AVERROR_INVALIDDATA;
}
- skip_input(s, mtd_size + 1);
- return 0;
+ return skip_input(s, mtd_size + 1);
}
static int parse_metadata_ext(DBEContext *s)
{
if (s->mtd_ext_size)
- skip_input(s, s->key_present + s->mtd_ext_size + 1);
+ return skip_input(s, s->key_present + s->mtd_ext_size + 1);
return 0;
}
@@ -455,7 +463,10 @@ static int parse_channel(DBEContext *s, int ch, int seg_id)
static int parse_audio(DBEContext *s, int start, int end, int seg_id)
{
- int ch, ret, key = parse_key(s);
+ int ch, ret, key;
+
+ if ((key = parse_key(s)) < 0)
+ return key;
for (ch = start; ch < end; ch++) {
if (!s->ch_size[ch]) {
@@ -469,17 +480,17 @@ static int parse_audio(DBEContext *s, int start, int end, int seg_id)
return ret;
s->channels[seg_id][ch].nb_groups = 0;
}
- skip_input(s, s->ch_size[ch]);
+ if ((ret = skip_input(s, s->ch_size[ch])) < 0)
+ return ret;
}
- skip_input(s, 1);
- return 0;
+ return skip_input(s, 1);
}
static int parse_meter(DBEContext *s)
{
if (s->meter_size)
- skip_input(s, s->key_present + s->meter_size + 1);
+ return skip_input(s, s->key_present + s->meter_size + 1);
return 0;
}