Bug 1127554 - Make MP4Sample::Pad fallible. v1 r=mattwoodrow
authorBobby Holley <bobbyholley@gmail.com>
Wed, 11 Feb 2015 14:36:21 -0800
changeset 249914 c975f91c0466ec8d1c23c0d327df47ac373e5dfb
parent 249913 bbda80b65439a11b7f7c4d1ffb4540465894a7c1
child 249915 65f0b6f7cb54fd130fe295e35808e4cfc95bc0f6
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1127554
milestone37.0a2
Bug 1127554 - Make MP4Sample::Pad fallible. v1 r=mattwoodrow
dom/media/fmp4/ffmpeg/FFmpegAudioDecoder.cpp
dom/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp
media/libstagefright/binding/DecoderData.cpp
media/libstagefright/binding/include/mp4_demuxer/DecoderData.h
--- a/dom/media/fmp4/ffmpeg/FFmpegAudioDecoder.cpp
+++ b/dom/media/fmp4/ffmpeg/FFmpegAudioDecoder.cpp
@@ -83,17 +83,22 @@ CopyAndPackAudio(AVFrame* aFrame, uint32
 }
 
 void
 FFmpegAudioDecoder<LIBAV_VER>::DecodePacket(MP4Sample* aSample)
 {
   AVPacket packet;
   av_init_packet(&packet);
 
-  aSample->Pad(FF_INPUT_BUFFER_PADDING_SIZE);
+  if (!aSample->Pad(FF_INPUT_BUFFER_PADDING_SIZE)) {
+    NS_WARNING("FFmpeg audio decoder failed to allocate sample.");
+    mCallback->Error();
+    return;
+  }
+
   packet.data = aSample->data;
   packet.size = aSample->size;
 
   if (!PrepareFrame()) {
     NS_WARNING("FFmpeg audio decoder failed to allocate frame.");
     mCallback->Error();
     return;
   }
--- a/dom/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp
+++ b/dom/media/fmp4/ffmpeg/FFmpegH264Decoder.cpp
@@ -49,17 +49,22 @@ FFmpegH264Decoder<LIBAV_VER>::Init()
 
 FFmpegH264Decoder<LIBAV_VER>::DecodeResult
 FFmpegH264Decoder<LIBAV_VER>::DoDecodeFrame(mp4_demuxer::MP4Sample* aSample)
 {
   AVPacket packet;
   av_init_packet(&packet);
 
   mp4_demuxer::AnnexB::ConvertSampleToAnnexB(aSample);
-  aSample->Pad(FF_INPUT_BUFFER_PADDING_SIZE);
+  if (!aSample->Pad(FF_INPUT_BUFFER_PADDING_SIZE)) {
+    NS_WARNING("FFmpeg h264 decoder failed to allocate sample.");
+    mCallback->Error();
+    return DecodeResult::DECODE_ERROR;
+  }
+
   packet.data = aSample->data;
   packet.size = aSample->size;
   packet.dts = aSample->decode_timestamp;
   packet.pts = aSample->composition_timestamp;
   packet.flags = aSample->is_sync_point ? AV_PKT_FLAG_KEY : 0;
   packet.pos = aSample->byte_offset;
 
   if (!PrepareFrame()) {
--- a/media/libstagefright/binding/DecoderData.cpp
+++ b/media/libstagefright/binding/DecoderData.cpp
@@ -249,37 +249,42 @@ MP4Sample::Update(int64_t& aMediaTime, i
   byte_offset = FindInt64(m, kKey64BitFileOffset);
   is_sync_point = FindInt32(m, kKeyIsSyncFrame);
   data = reinterpret_cast<uint8_t*>(mMediaBuffer->data());
   size = mMediaBuffer->range_length();
 
   crypto.Update(m);
 }
 
-void
+bool
 MP4Sample::Pad(size_t aPaddingBytes)
 {
   size_t newSize = size + aPaddingBytes;
 
   // If the existing MediaBuffer has enough space then we just recycle it. If
   // not then we copy to a new buffer.
   uint8_t* newData = mMediaBuffer && newSize <= mMediaBuffer->size()
                        ? data
-                       : new uint8_t[newSize];
+                       : new (fallible) uint8_t[newSize];
+  if (!newData) {
+    return false;
+  }
 
   memset(newData + size, 0, aPaddingBytes);
 
   if (newData != data) {
     memcpy(newData, data, size);
     extra_buffer = data = newData;
     if (mMediaBuffer) {
       mMediaBuffer->release();
       mMediaBuffer = nullptr;
     }
   }
+
+  return true;
 }
 
 void
 MP4Sample::Prepend(const uint8_t* aData, size_t aSize)
 {
   size_t newSize = size + aSize;
 
   // If the existing MediaBuffer has enough space then we just recycle it. If
--- a/media/libstagefright/binding/include/mp4_demuxer/DecoderData.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/DecoderData.h
@@ -153,17 +153,17 @@ typedef int64_t Microseconds;
 
 class MP4Sample
 {
 public:
   MP4Sample();
   virtual ~MP4Sample();
   MP4Sample* Clone() const;
   void Update(int64_t& aMediaTime, int64_t& aTimestampOffset);
-  void Pad(size_t aPaddingBytes);
+  bool Pad(size_t aPaddingBytes);
 
   stagefright::MediaBuffer* mMediaBuffer;
 
   Microseconds decode_timestamp;
   Microseconds composition_timestamp;
   Microseconds duration;
   int64_t byte_offset;
   bool is_sync_point;