Strip EXIF metadata from all JPEG images.

Strip all EXIF metadata from all JPEGs by re-encoding the JPEG. This
will keep all of the necessary visual effects of the tags (by encoding
them directly in the image data) while stripped the EXIF tags
themselves.
This commit is contained in:
Greyson Parrelli 2018-03-19 11:22:39 -07:00 committed by Moxie Marlinspike
parent 10e5b24cfd
commit 7e1e666172
5 changed files with 20 additions and 6 deletions

View File

@ -175,7 +175,7 @@ public class MmsSendJob extends SendJob {
String lineNumber = getMyNumber(context);
Address destination = message.getRecipient().getAddress();
MediaConstraints mediaConstraints = MediaConstraints.getMmsMediaConstraints(message.getSubscriptionId());
List<Attachment> scaledAttachments = scaleAttachments(mediaConstraints, message.getAttachments());
List<Attachment> scaledAttachments = scaleAndStripExifFromAttachments(mediaConstraints, message.getAttachments());
if (!TextUtils.isEmpty(lineNumber)) {
req.setFrom(new EncodedStringValue(lineNumber));

View File

@ -141,7 +141,7 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
Optional<byte[]> profileKey = getProfileKey(message.getRecipient());
List<Address> recipients = getGroupMessageRecipients(groupId, messageId);
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
List<Attachment> scaledAttachments = scaleAttachments(mediaConstraints, message.getAttachments());
List<Attachment> scaledAttachments = scaleAndStripExifFromAttachments(mediaConstraints, message.getAttachments());
List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(scaledAttachments);
List<SignalServiceAddress> addresses;

View File

@ -107,7 +107,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
try {
SignalServiceAddress address = getPushAddress(message.getRecipient().getAddress());
MediaConstraints mediaConstraints = MediaConstraints.getPushMediaConstraints();
List<Attachment> scaledAttachments = scaleAttachments(mediaConstraints, message.getAttachments());
List<Attachment> scaledAttachments = scaleAndStripExifFromAttachments(mediaConstraints, message.getAttachments());
List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(scaledAttachments);
Optional<byte[]> profileKey = getProfileKey(message.getRecipient());
SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder()

View File

@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.mms.MediaStream;
import org.thoughtcrime.securesms.mms.MmsException;
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.jobqueue.JobParameters;
@ -50,8 +51,8 @@ public abstract class SendJob extends MasterSecretJob {
}
}
protected List<Attachment> scaleAttachments(@NonNull MediaConstraints constraints,
@NonNull List<Attachment> attachments)
protected List<Attachment> scaleAndStripExifFromAttachments(@NonNull MediaConstraints constraints,
@NonNull List<Attachment> attachments)
throws UndeliverableMessageException
{
AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context);
@ -60,7 +61,12 @@ public abstract class SendJob extends MasterSecretJob {
for (Attachment attachment : attachments) {
try {
if (constraints.isSatisfied(context, attachment)) {
results.add(attachment);
if (MediaUtil.isJpeg(attachment)) {
MediaStream stripped = constraints.getResizedMedia(context, attachment);
results.add(attachmentDatabase.updateAttachmentData(attachment, stripped));
} else {
results.add(attachment);
}
} else if (constraints.canResize(attachment)) {
MediaStream resized = constraints.getResizedMedia(context, attachment);
results.add(attachmentDatabase.updateAttachmentData(attachment, resized));

View File

@ -149,6 +149,10 @@ public class MediaUtil {
return isGif(attachment.getContentType());
}
public static boolean isJpeg(Attachment attachment) {
return isJpegType(attachment.getContentType());
}
public static boolean isImage(Attachment attachment) {
return isImageType(attachment.getContentType());
}
@ -169,6 +173,10 @@ public class MediaUtil {
return !TextUtils.isEmpty(contentType) && contentType.trim().equals("image/gif");
}
public static boolean isJpegType(String contentType) {
return !TextUtils.isEmpty(contentType) && contentType.trim().equals(IMAGE_JPEG);
}
public static boolean isFile(Attachment attachment) {
return !isGif(attachment) && !isImage(attachment) && !isAudio(attachment) && !isVideo(attachment);
}