Bug 816994 - Skip Opus packets with invalid lengths. r=derf
authorRalph Giles <giles@mozilla.com>
Tue, 11 Dec 2012 11:25:10 -0800
changeset 116451 746f31757355d228a158f7a94940eea3659d4e64
parent 116450 ef0483c37e00dce2b1273d912e93cf5aea858ca1
child 116452 ce816b018b0a383e693c541342cd4cd3153f9d99
push id24052
push useremorley@mozilla.com
push dateWed, 19 Dec 2012 19:30:46 +0000
treeherdermozilla-central@27a1c1839d42 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersderf
bugs816994
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 816994 - Skip Opus packets with invalid lengths. r=derf Reject Opus packets less than 2.5 ms or more than 120 ms in length, which are invalid by the spec. Also explicitly check for error after opus_packet_get_nb_frames() since this could indicate the subsequent call to opus_packet_get_samples_per_frame() call will segfault because the packet buffer length is invalid. Based on a patch by Tim Terriberry.
content/media/ogg/OggReader.cpp
--- a/content/media/ogg/OggReader.cpp
+++ b/content/media/ogg/OggReader.cpp
@@ -416,24 +416,27 @@ nsresult OggReader::DecodeVorbis(ogg_pac
     }
   }
   return NS_OK;
 }
 #ifdef MOZ_OPUS
 nsresult OggReader::DecodeOpus(ogg_packet* aPacket) {
   NS_ASSERTION(aPacket->granulepos != -1, "Must know opus granulepos!");
 
-  // Maximum value is 63*2880.
+  // Maximum value is 63*2880, so there's no chance of overflow.
   int32_t frames_number = opus_packet_get_nb_frames(aPacket->packet,
                                                     aPacket->bytes);
+  if (frames_number <= 0)
+    return NS_ERROR_FAILURE; // Invalid packet header.
   int32_t samples = opus_packet_get_samples_per_frame(aPacket->packet,
                                                       (opus_int32) mOpusState->mRate);
   int32_t frames = frames_number*samples;
 
-  if (frames <= 0)
+  // A valid Opus packet must be between 2.5 and 120 ms long.
+  if (frames < 120 || frames > 5760)
     return NS_ERROR_FAILURE;
   uint32_t channels = mOpusState->mChannels;
   nsAutoArrayPtr<AudioDataValue> buffer(new AudioDataValue[frames * channels]);
 
   // Decode to the appropriate sample type.
 #ifdef MOZ_SAMPLE_TYPE_FLOAT32
   int ret = opus_multistream_decode_float(mOpusState->mDecoder,
                                           aPacket->packet, aPacket->bytes,