Rejects bad multistream frame length
[opus.git] / src / opus_decoder.c
index 5e39bd4..1f39578 100644 (file)
@@ -268,7 +268,9 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
          return audiosize;
       }
 
          return audiosize;
       }
 
-      if (mode != MODE_SILK_ONLY && audiosize > F20)
+      /* Avoids trying to run the PLC on sizes other than 2.5 (CELT), 5 (CELT),
+         10, or 20 (e.g. 12.5 or 30 ms). */
+      if (audiosize > F20)
       {
          do {
             int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0);
       {
          do {
             int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0);
@@ -282,6 +284,12 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
          } while (audiosize > 0);
          RESTORE_STACK;
          return frame_size;
          } while (audiosize > 0);
          RESTORE_STACK;
          return frame_size;
+      } else if (audiosize < F20)
+      {
+         if (audiosize > F10)
+            audiosize = F10;
+         else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10)
+            audiosize = F5;
       }
    }
 
       }
    }
 
@@ -708,7 +716,7 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
             return OPUS_INVALID_PACKET;
          for (i=0;i<count-1;i++)
             size[i] = size[count-1];
             return OPUS_INVALID_PACKET;
          for (i=0;i<count-1;i++)
             size[i] = size[count-1];
-      } else if(size[count-1] > last_size)
+      } else if (bytes+size[count-1] > last_size)
          return OPUS_INVALID_PACKET;
    } else
    {
          return OPUS_INVALID_PACKET;
    } else
    {