Bug 1048097 - Delete the GMPBuffer we send into GMP/CDM for decryption once it's been returned decrypted. r=jesup
--- 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;
};