Skip to content

Commit

Permalink
Retain cropData object in ImageEditingManager.cropImage
Browse files Browse the repository at this point in the history
Summary:
All struct args are passed into NativeModule methods via references. If blocks access those references, we don't move those references to the heap. This means that by the time that the block accesses the struct arg, it could be freed. This can crash the program.

The solution is simple: we copy the struct arg, and access the copy in the block. This ensures that the block will make a copy, which prevents the underlying data structures from being released by the time that the block accesses the struct arg.

Changelog:
[iOS][Fixed] - Retain cropData struct arg in ImageEditingManager.cropImage call

Differential Revision: D18076026

fbshipit-source-id: 1a7bb602606ff1afac38ad5451662c82fa86f205
  • Loading branch information
RSNara authored and facebook-github-bot committed Oct 23, 2019
1 parent 94845b5 commit 002d3c1
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions Libraries/Image/RCTImageEditingManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ @implementation RCTImageEditingManager
@"height": @(cropData.size().height()),
}]
};

// We must keep a copy of cropData so that we can access data from it at a later time
JS::NativeImageEditor::Options cropDataCopy = cropData;

[[_bridge moduleForName:@"ImageLoader" lazilyLoadIfNecessary:YES]
loadImageWithURLRequest:imageRequest callback:^(NSError *error, UIImage *image) {
Expand All @@ -68,9 +71,9 @@ @implementation RCTImageEditingManager
UIImage *croppedImage = RCTTransformImage(image, targetSize, image.scale, transform);

// Scale image
if (cropData.displaySize()) {
targetSize = [RCTConvert CGSize:@{@"width": @(cropData.displaySize()->width()), @"height": @(cropData.displaySize()->height())}]; // in pixels
RCTResizeMode resizeMode = [RCTConvert RCTResizeMode:cropData.resizeMode() ?: @"contain"];
if (cropDataCopy.displaySize()) {
targetSize = [RCTConvert CGSize:@{@"width": @(cropDataCopy.displaySize()->width()), @"height": @(cropDataCopy.displaySize()->height())}]; // in pixels
RCTResizeMode resizeMode = [RCTConvert RCTResizeMode:cropDataCopy.resizeMode() ?: @"contain"];
targetRect = RCTTargetRect(croppedImage.size, targetSize, 1, resizeMode);
transform = RCTTransformFromTargetRect(croppedImage.size, targetRect);
croppedImage = RCTTransformImage(croppedImage, targetSize, image.scale, transform);
Expand Down

0 comments on commit 002d3c1

Please sign in to comment.