Avoid reading uninitialized values (outside baundary) in DFT arithmatic decoder of iSAC-fix.

Arithmetic encoder does not right the last 2 or 3 bytes of |streamval| when terminating the bit-stream. Perhaps the last bytes makes no difference in decoding the stream. However, the decoder reads full |streamval| (int16_t) going out of boundary and reading uninitialized values. This avoids this problem. by inserting zero-bytes whenever decoder intends to read outside boundary.

BUG=1353,chrome373312,b/13468260
R=tina.legrand@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/16499005

git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@6234 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c b/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c
index b540ed5..62a20a2 100644
--- a/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c
+++ b/modules/audio_coding/codecs/isac/fix/source/arith_routines_logist.c
@@ -248,7 +248,7 @@
   int16_t     envCount;
   uint16_t    tmpARSpecQ8 = 0;
   int             k, i;
-
+  int offset = 0;
 
   /* point to beginning of stream buffer */
   streamPtr = streamData->stream + streamData->stream_index;
@@ -377,14 +377,27 @@
        * W_upper < 2^24 */
       while ( !(W_upper & 0xFF000000) )
       {
-        /* read next byte from stream */
-        if (streamData->full == 0) {
-          streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) | (*streamPtr++ & 0x00FF);
-          streamData->full = 1;
+        if (streamPtr < streamData->stream + streamData->stream_size) {
+          /* read next byte from stream */
+          if (streamData->full == 0) {
+            streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) | (*streamPtr++ & 0x00FF);
+            streamData->full = 1;
+          } else {
+            streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) |
+                WEBRTC_SPL_RSHIFT_U16(*streamPtr, 8);
+            streamData->full = 0;
+          }
         } else {
-          streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8) |
-              WEBRTC_SPL_RSHIFT_U16(*streamPtr, 8);
-          streamData->full = 0;
+          /* Intending to read outside the stream. This can happen for the last
+           * two or three bytes. It is how the algorithm is implemented. Do
+           * not read from the bit stream and insert zeros instead. */
+          streamVal = WEBRTC_SPL_LSHIFT_W32(streamVal, 8);
+          if (streamData->full == 0) {
+            offset++;  // We would have incremented the pointer in this case.
+            streamData->full = 1;
+          } else {
+            streamData->full = 0;
+          }
         }
         W_upper = WEBRTC_SPL_LSHIFT_W32(W_upper, 8);
       }
@@ -392,7 +405,7 @@
     envCount++;
   }
 
-  streamData->stream_index = streamPtr - streamData->stream;
+  streamData->stream_index = streamPtr + offset - streamData->stream;
   streamData->W_upper = W_upper;
   streamData->streamval = streamVal;
 
diff --git a/modules/audio_coding/codecs/isac/fix/source/isacfix.c b/modules/audio_coding/codecs/isac/fix/source/isacfix.c
index 8baa307..30e6f67 100644
--- a/modules/audio_coding/codecs/isac/fix/source/isacfix.c
+++ b/modules/audio_coding/codecs/isac/fix/source/isacfix.c
@@ -791,6 +791,7 @@
   }
 
   (ISAC_inst->ISACdec_obj.bitstr_obj).stream = (uint16_t *)encoded;
+  ISAC_inst->ISACdec_obj.bitstr_obj.stream_size = (len + 1) >> 1;
 
   /* convert bitstream from int16_t to bytes */
 #ifndef WEBRTC_ARCH_BIG_ENDIAN
diff --git a/modules/audio_coding/codecs/isac/fix/source/structs.h b/modules/audio_coding/codecs/isac/fix/source/structs.h
index 4d04356..b4d2bd8 100644
--- a/modules/audio_coding/codecs/isac/fix/source/structs.h
+++ b/modules/audio_coding/codecs/isac/fix/source/structs.h
@@ -33,6 +33,7 @@
   int16_t   full;             /* 0 - first byte in memory filled, second empty*/
   /* 1 - both bytes are empty (we just filled the previous memory */
 
+  int stream_size;  /* The size of stream. */
 } Bitstr_dec;
 
 /* Bitstream struct for encoder */