From ef5de19bd0d24f53e839c5d63a676e4043d67dd5 Mon Sep 17 00:00:00 2001 From: Mathis Rosenhauer Date: Tue, 26 Feb 2013 14:03:29 +0100 Subject: [PATCH] Fix crash when input data isn't a multiple of the storage size --- README | 10 ++++++---- src/encode.c | 12 ++++++------ src/encode.h | 1 + 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/README b/README index 5980c67..440e4be 100644 --- a/README +++ b/README @@ -124,10 +124,12 @@ sample size storage size 9 - 16 bit 2 bytes 17 - 32 bit 4 bytes (also for 24bit if AEC_DATA_3BYTE is not set) -If you use less bits than the storage size provides, then you have to -make sure that unused bits are not set. Libaec does not check this for -performance reasons and will produce undefined output if unused bits -are set. +If a sample requires less bits than the storage size provides, then +you have to make sure that unused bits are not set. Libaec does not +check this for performance reasons and will produce undefined output +if unused bits are set. All input data must be a multiple of the +storage size in bytes. Remaining bytes which do not form a complete +sample will be ignored. Libaec accesses next_in and next_out buffers only bytewise. There are no alignment requirements for these buffers. diff --git a/src/encode.c b/src/encode.c index 587c919..d18dd34 100644 --- a/src/encode.c +++ b/src/encode.c @@ -686,7 +686,7 @@ static int m_get_rsi_resumable(struct aec_stream *strm) struct internal_state *state = strm->state; do { - if (strm->avail_in > 0) { + if (strm->avail_in >= state->bytes_per_sample) { state->data_raw[state->i] = state->get_sample(strm); } else { if (state->flush == AEC_FLUSH) { @@ -796,7 +796,7 @@ int aec_encode_init(struct aec_stream *strm) if (strm->bits_per_sample <= 24 && strm->flags & AEC_DATA_3BYTE) { - state->rsi_len = 3; + state->bytes_per_sample = 3; if (strm->flags & AEC_DATA_MSB) { state->get_sample = aec_get_msb_24; state->get_rsi = aec_get_rsi_msb_24; @@ -805,7 +805,7 @@ int aec_encode_init(struct aec_stream *strm) state->get_rsi = aec_get_rsi_lsb_24; } } else { - state->rsi_len = 4; + state->bytes_per_sample = 4; if (strm->flags & AEC_DATA_MSB) { state->get_sample = aec_get_msb_32; state->get_rsi = aec_get_rsi_msb_32; @@ -818,7 +818,7 @@ int aec_encode_init(struct aec_stream *strm) else if (strm->bits_per_sample > 8) { /* 16 bit settings */ state->id_len = 4; - state->rsi_len = 2; + state->bytes_per_sample = 2; if (strm->flags & AEC_DATA_MSB) { state->get_sample = aec_get_msb_16; @@ -830,12 +830,12 @@ int aec_encode_init(struct aec_stream *strm) } else { /* 8 bit settings */ state->id_len = 3; - state->rsi_len = 1; + state->bytes_per_sample = 1; state->get_sample = aec_get_8; state->get_rsi = aec_get_rsi_8; } - state->rsi_len *= strm->rsi * strm->block_size; + state->rsi_len = strm->rsi * strm->block_size * state->bytes_per_sample; if (strm->flags & AEC_DATA_SIGNED) { state->xmin = -(1ULL << (strm->bits_per_sample - 1)); diff --git a/src/encode.h b/src/encode.h index f2359fd..c2a1ba2 100644 --- a/src/encode.h +++ b/src/encode.h @@ -95,6 +95,7 @@ struct internal_state { * not */ int zero_ref; /* current zero block has a reference sample */ uint32_t zero_ref_sample;/* reference sample of zero block */ + int bytes_per_sample; /* storage size of samples in bytes */ int zero_blocks; /* number of contiguous zero blocks */ int block_nonzero; /* 1 if this is the first non-zero block * after one or more zero blocks */ -- 2.7.4