Enforce L1 media restrictions on link preview thumbnails.

Co-Authored-By: Alexandre Erwin Ittner <110642+ittner@users.noreply.github.com>
This commit is contained in:
Alex Hart 2022-04-04 12:06:17 -03:00 committed by Cody Henthorne
parent 092b30f64f
commit 4c462bd75a
2 changed files with 64 additions and 22 deletions

View file

@ -32,6 +32,7 @@ import org.thoughtcrime.securesms.jobs.AvatarGroupsV2DownloadJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil.OpenGraph; import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil.OpenGraph;
import org.thoughtcrime.securesms.mms.GlideApp; import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.PushMediaConstraints;
import org.thoughtcrime.securesms.net.CallRequestController; import org.thoughtcrime.securesms.net.CallRequestController;
import org.thoughtcrime.securesms.net.CompositeRequestController; import org.thoughtcrime.securesms.net.CompositeRequestController;
import org.thoughtcrime.securesms.net.RequestController; import org.thoughtcrime.securesms.net.RequestController;
@ -42,8 +43,10 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.stickers.StickerRemoteUri; import org.thoughtcrime.securesms.stickers.StickerRemoteUri;
import org.thoughtcrime.securesms.stickers.StickerUrl; import org.thoughtcrime.securesms.stickers.StickerUrl;
import org.thoughtcrime.securesms.util.AvatarUtil; import org.thoughtcrime.securesms.util.AvatarUtil;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.ByteUnit; import org.thoughtcrime.securesms.util.ByteUnit;
import org.signal.core.util.Hex; import org.signal.core.util.Hex;
import org.thoughtcrime.securesms.util.ImageCompressionUtil;
import org.thoughtcrime.securesms.util.MediaUtil; import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.OkHttpUtil; import org.thoughtcrime.securesms.util.OkHttpUtil;
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver; import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
@ -187,14 +190,33 @@ public class LinkPreviewRepository {
InputStream bodyStream = response.body().byteStream(); InputStream bodyStream = response.body().byteStream();
controller.setStream(bodyStream); controller.setStream(bodyStream);
byte[] data = OkHttpUtil.readAsBytes(bodyStream, FAILSAFE_MAX_IMAGE_SIZE); byte[] data = OkHttpUtil.readAsBytes(bodyStream, FAILSAFE_MAX_IMAGE_SIZE);
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Optional<Attachment> thumbnail = bitmapToAttachment(bitmap, Bitmap.CompressFormat.JPEG, MediaUtil.IMAGE_JPEG); Optional<Attachment> thumbnail = Optional.empty();
PushMediaConstraints.MediaConfig mediaConfig = PushMediaConstraints.MediaConfig.getDefault(ApplicationDependencies.getApplication());
if (bitmap != null) {
for (final int maxDimension : mediaConfig.getImageSizeTargets()) {
ImageCompressionUtil.Result result = ImageCompressionUtil.compressWithinConstraints(
ApplicationDependencies.getApplication(),
MediaUtil.IMAGE_JPEG,
bitmap,
maxDimension,
mediaConfig.getMaxImageFileSize(),
mediaConfig.getQualitySetting()
);
if (result != null) {
thumbnail = Optional.of(bytesToAttachment(result.getData(), result.getWidth(), result.getHeight(), result.getMimeType()));
break;
}
}
}
if (bitmap != null) bitmap.recycle(); if (bitmap != null) bitmap.recycle();
callback.accept(thumbnail); callback.accept(thumbnail);
} catch (IOException | IllegalArgumentException e) { } catch (IOException | IllegalArgumentException | BitmapDecodingException e) {
Log.w(TAG, "Exception during link preview image retrieval.", e); Log.w(TAG, "Exception during link preview image retrieval.", e);
controller.cancel(); controller.cancel();
callback.accept(Optional.empty()); callback.accept(Optional.empty());
@ -332,25 +354,33 @@ public class LinkPreviewRepository {
bitmap.compress(format, 80, baos); bitmap.compress(format, 80, baos);
byte[] bytes = baos.toByteArray(); byte[] bytes = baos.toByteArray();
Uri uri = BlobProvider.getInstance().forData(bytes).createForSingleSessionInMemory(); return Optional.of(bytesToAttachment(bytes, bitmap.getWidth(), bitmap.getHeight(), contentType));
}
return Optional.of(new UriAttachment(uri, private static Attachment bytesToAttachment(byte[] bytes,
contentType, int width,
AttachmentDatabase.TRANSFER_PROGRESS_STARTED, int height,
bytes.length, @NonNull String contentType) {
bitmap.getWidth(),
bitmap.getHeight(), Uri uri = BlobProvider.getInstance().forData(bytes).createForSingleSessionInMemory();
null,
null, return new UriAttachment(uri,
false, contentType,
false, AttachmentDatabase.TRANSFER_PROGRESS_STARTED,
false, bytes.length,
false, width,
null, height,
null, null,
null, null,
null, false,
null)); false,
false,
false,
null,
null,
null,
null,
null);
} }
private static class Metadata { private static class Metadata {

View file

@ -117,6 +117,18 @@ public class PushMediaConstraints extends MediaConstraints {
this.qualitySetting = qualitySetting; this.qualitySetting = qualitySetting;
} }
public int getMaxImageFileSize() {
return maxImageFileSize;
}
public int[] getImageSizeTargets() {
return imageSizeTargets;
}
public int getQualitySetting() {
return qualitySetting;
}
public static @Nullable MediaConfig forLevel(int level) { public static @Nullable MediaConfig forLevel(int level) {
boolean isLowMemory = Util.isLowMemory(ApplicationDependencies.getApplication()); boolean isLowMemory = Util.isLowMemory(ApplicationDependencies.getApplication());