Added some bounds checking when reading bits, including a bug when forcing
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Tue, 7 Jan 2003 04:11:04 +0000 (04:11 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Tue, 7 Jan 2003 04:11:04 +0000 (04:11 +0000)
higher bit-rates (force-wb on a narrowband stream). Some cleaning up too.

git-svn-id: http://svn.xiph.org/trunk/speex@4212 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/bits.c
libspeex/ltp.c
libspeex/sb_celp.c
libspeex/speex_bits.h
src/speexdec.c

index 29752e3..cd48254 100644 (file)
@@ -46,6 +46,7 @@ void speex_bits_init(SpeexBits *bits)
    bits->bytePtr=0;
    bits->bitPtr=0;
    bits->owner=1;
+   bits->overflow=0;
 }
 
 void speex_bits_init_buffer(SpeexBits *bits, void *buff)
@@ -59,6 +60,7 @@ void speex_bits_init_buffer(SpeexBits *bits, void *buff)
    bits->bytePtr=0;
    bits->bitPtr=0;
    bits->owner=0;
+   bits->overflow=0;
 }
 
 void speex_bits_destroy(SpeexBits *bits)
@@ -76,12 +78,14 @@ void speex_bits_reset(SpeexBits *bits)
    bits->nbBits=0;
    bits->bytePtr=0;
    bits->bitPtr=0;
+   bits->overflow=0;
 }
 
 void speex_bits_rewind(SpeexBits *bits)
 {
    bits->bytePtr=0;
    bits->bitPtr=0;
+   bits->overflow=0;
 }
 
 void speex_bits_read_from(SpeexBits *bits, char *bytes, int len)
@@ -96,6 +100,7 @@ void speex_bits_read_from(SpeexBits *bits, char *bytes, int len)
    bits->nbBits=len<<3;
    bits->bytePtr=0;
    bits->bitPtr=0;
+   bits->overflow=0;
 }
 
 void speex_bits_flush(SpeexBits *bits)
@@ -184,6 +189,10 @@ int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
 unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
 {
    unsigned int d=0;
+   if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
+      bits->overflow=1;
+   if (bits->overflow)
+      return 0;
    while(nbBits)
    {
       d<<=1;
@@ -204,6 +213,12 @@ unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
    unsigned int d=0;
    int bitPtr, bytePtr;
    char *bytes;
+
+   if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits)
+     bits->overflow=1;
+   if (bits->overflow)
+      return 0;
+
    bitPtr=bits->bitPtr;
    bytePtr=bits->bytePtr;
    bytes = bits->bytes;
@@ -224,12 +239,22 @@ unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
 
 int speex_bits_peek(SpeexBits *bits)
 {
+   if ((bits->bytePtr<<3)+bits->bitPtr+1>bits->nbBits)
+      bits->overflow=1;
+   if (bits->overflow)
+      return 0;
    return (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
 }
 
 void speex_bits_advance(SpeexBits *bits, int n)
 {
    int nbytes, nbits;
+
+   if ((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits)
+      bits->overflow=1;
+   if (bits->overflow)
+      return;
+
    nbytes = n >> 3;
    nbits = n & 7;
    
@@ -243,6 +268,14 @@ void speex_bits_advance(SpeexBits *bits, int n)
    }
 }
 
+int speex_bits_remaining(SpeexBits *bits)
+{
+   if (bits->overflow)
+      return -1;
+   else
+      return bits->nbBits-((bits->bytePtr<<3)+bits->bitPtr);
+}
+
 int speex_bits_nbytes(SpeexBits *bits)
 {
    return ((bits->nbBits+7)>>3);
index ae0d3f1..afbdf1c 100644 (file)
@@ -312,9 +312,6 @@ int  *cdbk_index
    
    for (i=0;i<nsf;i++)
       exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
-#ifdef DEBUG
-   printf ("3-tap pitch = %d, gains = [%f %f %f]\n",pitch, gain[0], gain[1], gain[2]);
-#endif
    
    err1=0;
    err2=0;
@@ -323,9 +320,6 @@ int  *cdbk_index
    for (i=0;i<nsf;i++)
       err2+=(target[i]-gain[2]*x[0][i]-gain[1]*x[1][i]-gain[0]*x[2][i])
       * (target[i]-gain[2]*x[0][i]-gain[1]*x[1][i]-gain[0]*x[2][i]);
-#ifdef DEBUG
-   printf ("prediction gain = %f\n",err1/(err2+1));
-#endif
 
    return err2;
 }
@@ -465,9 +459,6 @@ float last_pitch_gain)
            for (i=0;i<3;i++)
               gain[i]*=fact;
 
-#ifdef DEBUG
-        printf ("recovered unquantized pitch: %d, gain: [%f %f %f] (fact=%f)\n", pitch, gain[0], gain[1], gain[2], fact);
-#endif
         }
 
       }
@@ -488,10 +479,6 @@ float last_pitch_gain)
    gain_val[1]=gain[1];
    gain_val[2]=gain[2];
 
-#ifdef DEBUG
-   printf ("unquantized pitch: %d %f %f %f\n", pitch, gain[0], gain[1], gain[2]);
-#endif
-
    {
       float *e[3];
       float *tmp2;
index caf6847..502af2d 100644 (file)
@@ -801,7 +801,7 @@ int sb_decode(void *state, SpeexBits *bits, float *out)
    float *low_pi_gain, *low_exc, *low_innov;
    float *awk1, *awk2, *awk3;
    float dtx;
-   
+
    st = (SBDecState*)state;
    stack=st->stack;
 
@@ -829,7 +829,10 @@ int sb_decode(void *state, SpeexBits *bits, float *out)
       }
       
       /*Check "wideband bit"*/
-      wideband = speex_bits_peek(bits);
+      if (speex_bits_remaining(bits)>0)
+         wideband = speex_bits_peek(bits);
+      else
+         wideband = 0;
       if (wideband)
       {
          /*Regular wideband frame, read the submode*/
index 8b9a133..22416e3 100644 (file)
@@ -45,11 +45,12 @@ extern "C" {
 
 /** Bit-packing data structure representing (part of) a bit-stream. */
 typedef struct SpeexBits {
-   char *bytes; /**< "raw" data */
-   int  nbBits; /**< Total number of bits stored in the stream*/
-   int  bytePtr; /**< Position of the byte "cursor" */
-   int  bitPtr;  /**< Position of the bit "cursor" within the current byte */
-   int  owner; /**< Does the struct "own" the "raw" buffer (member "bytes") */
+   char *bytes;   /**< "raw" data */
+   int   nbBits;  /**< Total number of bits stored in the stream*/
+   int   bytePtr; /**< Position of the byte "cursor" */
+   int   bitPtr;  /**< Position of the bit "cursor" within the current byte */
+   int   owner;   /**< Does the struct "own" the "raw" buffer (member "bytes") */
+   int   overflow;/**< Set to one if we try to read past the valid data */
 } SpeexBits;
 
 /** Initializes and allocates resources for a SpeexBits struct */
@@ -127,9 +128,15 @@ int speex_bits_peek(SpeexBits *bits);
  *
  * @param bits Bit-stream to operate on
  * @param n Number of bits to advance
- * */
+ */
 void speex_bits_advance(SpeexBits *bits, int n);
 
+/** Returns the number of bits remaining to be read in a stream
+ *
+ * @param bits Bit-stream to operate on
+ */
+int speex_bits_remaining(SpeexBits *bits);
+
 #ifdef __cplusplus
 }
 #endif
index 3e766ed..b5b8c1b 100644 (file)
@@ -569,6 +569,11 @@ int main(int argc, char **argv)
                      fprintf (stderr, "Decoding error: corrupted stream?\n");
                      break;
                   }
+                  if (speex_bits_remaining(&bits)<0)
+                  {
+                     fprintf (stderr, "Decoding overflow: corrupted stream?\n");
+                     break;
+                  }
                   if (channels==2)
                      speex_decode_stereo(output, frame_size, &stereo);