diff --git a/sky/engine/core/painting/CanvasImageDecoder.cpp b/sky/engine/core/painting/CanvasImageDecoder.cpp index 4dac958c30f28535f97f6520380c540004703472..df295d2436d4d0857706135f7b416e79bec1c052 100644 --- a/sky/engine/core/painting/CanvasImageDecoder.cpp +++ b/sky/engine/core/painting/CanvasImageDecoder.cpp @@ -49,18 +49,25 @@ void CanvasImageDecoder::initWithList(const Uint8List& list) { void CanvasImageDecoder::Decode(PassRefPtr buffer) { TRACE_EVENT0("blink", "CanvasImageDecoder::Decode"); + + // Destroy the callback after this function completes. The Dart closure + // associated with the callback may hold a reference to the ImageDecoder, + // resulting in a circular reference. + CHECK(callback_); + OwnPtr callback(callback_.release()); + OwnPtr decoder = ImageDecoder::create(*buffer.get(), ImageSource::AlphaPremultiplied, ImageSource::GammaAndColorProfileIgnored); // decoder can be null if the buffer we was empty and we couldn't even guess // what type of image to decode. if (!decoder) { - callback_->handleEvent(nullptr); + callback->handleEvent(nullptr); return; } decoder->setData(buffer.get(), true); if (decoder->failed() || decoder->frameCount() == 0) { - callback_->handleEvent(nullptr); + callback->handleEvent(nullptr); return; } @@ -68,11 +75,13 @@ void CanvasImageDecoder::Decode(PassRefPtr buffer) { ImageFrame* imageFrame = decoder->frameBufferAtIndex(0); RefPtr skImage = adoptRef(SkImage::NewFromBitmap(imageFrame->getSkBitmap())); resultImage->setImage(skImage.release()); - callback_->handleEvent(resultImage.get()); + callback->handleEvent(resultImage.get()); } void CanvasImageDecoder::RejectCallback() { - callback_->handleEvent(nullptr); + CHECK(callback_); + OwnPtr callback(callback_.release()); + callback->handleEvent(nullptr); } } // namespace blink