Fix crash when input data isn't a multiple of the storage size
authorMathis Rosenhauer <rosenhauer@dkrz.de>
Tue, 26 Feb 2013 13:03:29 +0000 (14:03 +0100)
committerMathis Rosenhauer <rosenhauer@dkrz.de>
Tue, 26 Feb 2013 13:03:29 +0000 (14:03 +0100)
README
src/encode.c
src/encode.h

diff --git a/README b/README
index 5980c67..440e4be 100644 (file)
--- 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.
index 587c919..d18dd34 100644 (file)
@@ -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));
index f2359fd..c2a1ba2 100644 (file)
@@ -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 */