Bug 1048097 - Delete the GMPBuffer we send into GMP/CDM for decryption once it's been returned decrypted. r=jesup
☠☠ backed out by 58622922646d ☠ ☠
authorChris Pearce <cpearce@mozilla.com>
Tue, 05 Aug 2014 10:18:12 +1200
changeset 197748 ef8d10dc39274b0987dec6c07edf8dab0aaad701
parent 197747 f4634a64d20ea34cd46c2ddb00947921cadfba33
child 197749 a38bb1a95176a35d14c321fbe4898c4ee616dc9d
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjesup
bugs1048097
milestone34.0a1
Bug 1048097 - Delete the GMPBuffer we send into GMP/CDM for decryption once it's been returned decrypted. r=jesup
content/media/gmp/GMPDecryptorChild.cpp
content/media/gmp/gmp-api/gmp-decryption.h
--- a/content/media/gmp/GMPDecryptorChild.cpp
+++ b/content/media/gmp/GMPDecryptorChild.cpp
@@ -144,18 +144,23 @@ GMPDecryptorChild::KeyIdNotUsable(const 
   SendKeyIdNotUsable(sid, kid);
 }
 
 void
 GMPDecryptorChild::Decrypted(GMPBuffer* aBuffer, GMPErr aResult)
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 
+  if (!aBuffer) {
+    NS_WARNING("GMPDecryptorCallback passed bull GMPBuffer");
+    return;
+  }
   auto buffer = static_cast<GMPBufferImpl*>(aBuffer);
   SendDecrypted(buffer->mId, aResult, buffer->mData);
+  delete buffer;
 }
 
 void
 GMPDecryptorChild::SetCapabilities(uint64_t aCaps)
 {
   MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
 
   SendSetCaps(aCaps);
@@ -302,16 +307,18 @@ GMPDecryptorChild::RecvDecrypt(const uin
                                const GMPDecryptionData& aMetadata)
 {
   if (!mSession) {
     return false;
   }
 
   GMPEncryptedBufferDataImpl metadata(aMetadata);
 
+  // Note: the GMPBufferImpl created here is deleted when the GMP passes
+  // it back in the Decrypted() callback above.
   mSession->Decrypt(new GMPBufferImpl(aId, aBuffer), &metadata);
   return true;
 }
 
 bool
 GMPDecryptorChild::RecvDecryptingComplete()
 {
   if (!mSession) {
--- a/content/media/gmp/gmp-api/gmp-decryption.h
+++ b/content/media/gmp/gmp-api/gmp-decryption.h
@@ -252,16 +252,19 @@ public:
                                     const uint8_t* aServerCert,
                                     uint32_t aServerCertSize) = 0;
 
   // Asynchronously decrypts aBuffer in place. When the decryption is
   // complete, GMPDecryptor should write the decrypted data back into the
   // same GMPBuffer object and return it to Gecko by calling Decrypted(),
   // with the GMPNoErr successcode. If decryption fails, call Decrypted()
   // with a failure code, and an error event will fire on the media element.
+  // Note: When Decrypted() is called and aBuffer is passed back, aBuffer
+  // is deleted. Don't forget to call Decrypted(), as otherwise aBuffer's
+  // memory will leak!
   virtual void Decrypt(GMPBuffer* aBuffer,
                        GMPEncryptedBufferMetadata* aMetadata) = 0;
 
   // Called when the decryption operations are complete.
   // Do not call the GMPDecryptorCallback's functions after this is called.
   virtual void DecryptingComplete() = 0;
 
 };