Commit 62f82d00 authored by Mathis Rosenhauer's avatar Mathis Rosenhauer

Fail or return 0 if input runs dry

Found by libFuzzer
parent 8cd1a00d
...@@ -229,7 +229,6 @@ static inline uint32_t direct_get(struct aec_stream *strm, int n) ...@@ -229,7 +229,6 @@ static inline uint32_t direct_get(struct aec_stream *strm, int n)
struct internal_state *state = strm->state; struct internal_state *state = strm->state;
int b; int b;
if (state->bitp < n) if (state->bitp < n)
{ {
b = (63 - state->bitp) >> 3; b = (63 - state->bitp) >> 3;
...@@ -308,6 +307,9 @@ static inline uint32_t direct_get_fs(struct aec_stream *strm) ...@@ -308,6 +307,9 @@ static inline uint32_t direct_get_fs(struct aec_stream *strm)
state->acc = 0; state->acc = 0;
while (state->acc == 0) { while (state->acc == 0) {
if (strm->avail_in < 7)
return 0;
state->acc = (state->acc << 56) state->acc = (state->acc << 56)
| ((uint64_t)strm->next_in[0] << 48) | ((uint64_t)strm->next_in[0] << 48)
| ((uint64_t)strm->next_in[1] << 40) | ((uint64_t)strm->next_in[1] << 40)
...@@ -475,6 +477,9 @@ static int m_split(struct aec_stream *strm) ...@@ -475,6 +477,9 @@ static int m_split(struct aec_stream *strm)
state->rsip[i] = direct_get_fs(strm) << k; state->rsip[i] = direct_get_fs(strm) << k;
if (k) { if (k) {
if (strm->avail_in < (k * strm->block_size) / 8 + 9)
return M_ERROR;
for (i = state->ref; i < strm->block_size; i++) for (i = state->ref; i < strm->block_size; i++)
*state->rsip++ += direct_get(strm, k); *state->rsip++ += direct_get(strm, k);
} else { } else {
...@@ -566,6 +571,8 @@ static int m_se_decode(struct aec_stream *strm) ...@@ -566,6 +571,8 @@ static int m_se_decode(struct aec_stream *strm)
if (fs_ask(strm) == 0) if (fs_ask(strm) == 0)
return M_EXIT; return M_EXIT;
m = state->fs; m = state->fs;
if (m > SE_TABLE_SIZE)
return M_ERROR;
d1 = m - state->se_table[2 * m + 1]; d1 = m - state->se_table[2 * m + 1];
if ((state->i & 1) == 0) { if ((state->i & 1) == 0) {
...@@ -589,7 +596,8 @@ static int m_se_decode(struct aec_stream *strm) ...@@ -589,7 +596,8 @@ static int m_se_decode(struct aec_stream *strm)
static int m_se(struct aec_stream *strm) static int m_se(struct aec_stream *strm)
{ {
uint32_t i; uint32_t i;
int32_t m, d1; uint32_t m;
int32_t d1;
struct internal_state *state = strm->state; struct internal_state *state = strm->state;
if (BUFFERSPACE(strm)) { if (BUFFERSPACE(strm)) {
...@@ -597,6 +605,10 @@ static int m_se(struct aec_stream *strm) ...@@ -597,6 +605,10 @@ static int m_se(struct aec_stream *strm)
while (i < strm->block_size) { while (i < strm->block_size) {
m = direct_get_fs(strm); m = direct_get_fs(strm);
if (m > SE_TABLE_SIZE)
return M_ERROR;
d1 = m - state->se_table[2 * m + 1]; d1 = m - state->se_table[2 * m + 1];
if ((i & 1) == 0) { if ((i & 1) == 0) {
...@@ -763,7 +775,7 @@ int aec_decode_init(struct aec_stream *strm) ...@@ -763,7 +775,7 @@ int aec_decode_init(struct aec_stream *strm)
} }
state->in_blklen = (strm->block_size * strm->bits_per_sample state->in_blklen = (strm->block_size * strm->bits_per_sample
+ state->id_len) / 8 + 9; + state->id_len) / 8 + 16;
modi = 1UL << state->id_len; modi = 1UL << state->id_len;
state->id_table = malloc(modi * sizeof(int (*)(struct aec_stream *))); state->id_table = malloc(modi * sizeof(int (*)(struct aec_stream *)));
......
...@@ -63,6 +63,8 @@ ...@@ -63,6 +63,8 @@
#define MIN(a, b) (((a) < (b))? (a): (b)) #define MIN(a, b) (((a) < (b))? (a): (b))
#define SE_TABLE_SIZE 90
struct aec_stream; struct aec_stream;
struct internal_state { struct internal_state {
...@@ -89,7 +91,7 @@ struct internal_state { ...@@ -89,7 +91,7 @@ struct internal_state {
uint32_t xmax; uint32_t xmax;
/* length of uncompressed input block should be the longest /* length of uncompressed input block should be the longest
possible block */ legal block */
uint32_t in_blklen; uint32_t in_blklen;
/* length of output block in bytes */ /* length of output block in bytes */
...@@ -129,7 +131,7 @@ struct internal_state { ...@@ -129,7 +131,7 @@ struct internal_state {
uint32_t *flush_start; uint32_t *flush_start;
/* table for decoding second extension option */ /* table for decoding second extension option */
int se_table[182]; int se_table[2 * (SE_TABLE_SIZE + 1)];
} decode_state; } decode_state;
#endif /* DECODE_H */ #endif /* DECODE_H */
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