From af1762cce516b2fbfc920ed818bd9feaa41b33ea Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 28 Jan 2020 12:02:25 -0800 Subject: [PATCH] Fix crash in RCTImageComponentView.didReceiveImage Summary: Changelog: [Internal] I went over the ownership model in this call `_state->getData().getImageRequest().getImageInstrumentation().didSetImage();` 1. `getData()` returns reference to an object that is copied to state. 2. `getImageRequest()` returns a reference to an object that is strongly owned by `ImageState`. 3. `getImageInstrumentation()` returns a reference to an object that is strongly owned by `ImageRequest`. I don't think any of these can cause a crash, however `_state` can be nullptr. Reviewed By: shergin Differential Revision: D19599258 fbshipit-source-id: 317f03cd9a53d83f64ccbb9f9abfce10fcc1fae5 --- .../ComponentViews/Image/RCTImageComponentView.mm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm b/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm index fcf250a0829..e393dae3dab 100644 --- a/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm @@ -136,7 +136,7 @@ using namespace facebook::react; - (void)didReceiveImage:(UIImage *)image fromObserver:(void const *)observer { - if (!_eventEmitter) { + if (!_eventEmitter || !_state) { // Notifications are delivered asynchronously and might arrive after the view is already recycled. // In the future, we should incorporate an `EventEmitter` into a separate object owned by `ImageRequest` or `State`. // See for more info: T46311063. @@ -167,7 +167,12 @@ using namespace facebook::react; self->_imageView.layer.minificationFilter = kCAFilterTrilinear; self->_imageView.layer.magnificationFilter = kCAFilterTrilinear; - _state->getData().getImageRequest().getImageInstrumentation().didSetImage(); + auto data = _state->getData(); + auto instrumentation = std::static_pointer_cast( + data.getImageRequest().getSharedImageInstrumentation()); + if (instrumentation) { + instrumentation->didSetImage(); + } } - (void)didReceiveProgress:(float)progress fromObserver:(void const *)observer