Merge branch 'charlesmchen/contentTypeVsImageFormat'
This commit is contained in:
commit
e143b7ea2e
@ -645,7 +645,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSString *_Nullable filePath = [strongSelf.attachmentStream filePath];
|
||||
YYImage *_Nullable animatedImage = nil;
|
||||
if (filePath && [NSData ows_isValidImageAtPath:filePath]) {
|
||||
if (strongSelf.attachmentStream.isValidImage && filePath) {
|
||||
animatedImage = [YYImage imageWithContentsOfFile:filePath];
|
||||
}
|
||||
return animatedImage;
|
||||
|
||||
@ -383,7 +383,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [DebugUIMessagesAssetLoader
|
||||
fakeAssetLoaderWithUrl:@"https://s3.amazonaws.com/ows-data/example_attachment_media/random-gif.gif"
|
||||
mimeType:@"image/gif"];
|
||||
mimeType:OWSMimeTypeImageGif];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
@ -395,7 +395,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance =
|
||||
[DebugUIMessagesAssetLoader fakeAssetLoaderWithUrl:@"https://i.giphy.com/media/LTw0F3GAdaao8/source.gif"
|
||||
mimeType:@"image/gif"];
|
||||
mimeType:OWSMimeTypeImageGif];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
[scrollView autoPinToSuperviewEdges];
|
||||
|
||||
if (self.isAnimated) {
|
||||
if ([self.fileData ows_isValidImage]) {
|
||||
if (self.attachmentStream.isValidImage) {
|
||||
YYImage *animatedGif = [YYImage imageWithData:self.fileData];
|
||||
YYAnimatedImageView *animatedView = [YYAnimatedImageView new];
|
||||
animatedView.image = animatedGif;
|
||||
|
||||
@ -76,12 +76,12 @@
|
||||
|
||||
- (ConversationViewItem *)stillImageViewItem
|
||||
{
|
||||
return [self viewItemWithAttachmentMimetype:@"image/jpeg" filename:@"test-jpg.jpg"];
|
||||
return [self viewItemWithAttachmentMimetype:OWSMimeTypeImageJpeg filename:@"test-jpg.jpg"];
|
||||
}
|
||||
|
||||
- (ConversationViewItem *)animatedImageViewItem
|
||||
{
|
||||
return [self viewItemWithAttachmentMimetype:@"image/gif" filename:@"test-gif.gif"];
|
||||
return [self viewItemWithAttachmentMimetype:OWSMimeTypeImageGif filename:@"test-gif.gif"];
|
||||
}
|
||||
|
||||
- (ConversationViewItem *)videoViewItem
|
||||
|
||||
@ -2270,7 +2270,7 @@
|
||||
"VERIFICATION_STATE_CHANGE_GENERIC" = "Verification state changed.";
|
||||
|
||||
/* Label for button or row which allows users to verify the safety number of another user. */
|
||||
"VERIFY_PRIVACY" = "Show Safety Number";
|
||||
"VERIFY_PRIVACY" = "View Safety Number";
|
||||
|
||||
/* Label for button or row which allows users to verify the safety numbers of multiple users. */
|
||||
"VERIFY_PRIVACY_MULTIPLE" = "Review Safety Numbers";
|
||||
|
||||
@ -74,6 +74,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
// Non-nil for attachments which need "lazy backup restore."
|
||||
- (nullable OWSBackupFragment *)lazyRestoreFragment;
|
||||
|
||||
#pragma mark - Image Validation
|
||||
|
||||
- (BOOL)isValidImage;
|
||||
|
||||
#pragma mark - Update With... Methods
|
||||
|
||||
// Marks attachment as needing "lazy backup restore."
|
||||
|
||||
@ -312,6 +312,25 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
return [MIMETypeUtil isAudio:self.contentType];
|
||||
}
|
||||
|
||||
#pragma mark - Image Validation
|
||||
|
||||
- (BOOL)isValidImageWithData:(NSData *)data
|
||||
{
|
||||
OWSAssert(self.isImage || self.isAnimated);
|
||||
OWSAssert(data);
|
||||
|
||||
return [data ows_isValidImageWithMimeType:self.contentType];
|
||||
}
|
||||
|
||||
- (BOOL)isValidImage
|
||||
{
|
||||
OWSAssert(self.isImage || self.isAnimated);
|
||||
|
||||
return [NSData ows_isValidImageAtPath:self.filePath mimeType:self.contentType];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (nullable UIImage *)image
|
||||
{
|
||||
if ([self isVideo]) {
|
||||
@ -322,7 +341,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
return nil;
|
||||
}
|
||||
NSData *data = [NSData dataWithContentsOfURL:mediaUrl];
|
||||
if (![data ows_isValidImage]) {
|
||||
if (![self isValidImageWithData:data]) {
|
||||
return nil;
|
||||
}
|
||||
return [UIImage imageWithData:data];
|
||||
@ -348,7 +367,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
}
|
||||
|
||||
NSData *data = [NSData dataWithContentsOfURL:mediaUrl];
|
||||
if (![data ows_isValidImage]) {
|
||||
if (![self isValidImageWithData:data]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
@ -422,7 +441,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
UIImage *_Nullable result;
|
||||
if (self.isImage || self.isAnimated) {
|
||||
if (![NSData ows_isValidImageAtPath:self.filePath]) {
|
||||
if (![self isValidImage]) {
|
||||
DDLogWarn(@"%@ skipping thumbnail generation for invalid image at path: %@", self.logTag, self.filePath);
|
||||
return;
|
||||
}
|
||||
@ -516,7 +535,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
if (!mediaUrl) {
|
||||
return CGSizeZero;
|
||||
}
|
||||
if (![NSData ows_isValidImageAtPath:mediaUrl.path]) {
|
||||
if (![self isValidImage]) {
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
// if ows_isValidImage is given a file path, it will
|
||||
// avoid loading most of the data into memory, which
|
||||
// is considerably more performant, so try to do that.
|
||||
return [NSData ows_isValidImageAtPath:dataPath];
|
||||
return [NSData ows_isValidImageAtPath:dataPath mimeType:self.mimeType];
|
||||
}
|
||||
NSData *data = [self data];
|
||||
return [data ows_isValidImage];
|
||||
@ -83,6 +83,14 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
_sourceFilename = sourceFilename.filterFilename;
|
||||
}
|
||||
|
||||
// Returns the MIME type, if known.
|
||||
- (nullable NSString *)mimeType
|
||||
{
|
||||
OWS_ABSTRACT_METHOD();
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
@ -222,6 +230,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
}
|
||||
}
|
||||
|
||||
- (nullable NSString *)mimeType
|
||||
{
|
||||
return (self.fileExtension ? [MIMETypeUtil mimeTypeForFileExtension:self.fileExtension] : nil);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
@ -372,6 +385,12 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
}
|
||||
}
|
||||
|
||||
- (nullable NSString *)mimeType
|
||||
{
|
||||
NSString *_Nullable fileExtension = self.filePath.pathExtension;
|
||||
return (fileExtension ? [MIMETypeUtil mimeTypeForFileExtension:fileExtension] : nil);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -8,6 +8,11 @@ extern NSString *const OWSMimeTypeApplicationOctetStream;
|
||||
extern NSString *const OWSMimeTypeApplicationZip;
|
||||
extern NSString *const OWSMimeTypeImagePng;
|
||||
extern NSString *const OWSMimeTypeImageJpeg;
|
||||
extern NSString *const OWSMimeTypeImageGif;
|
||||
extern NSString *const OWSMimeTypeImageTiff1;
|
||||
extern NSString *const OWSMimeTypeImageTiff2;
|
||||
extern NSString *const OWSMimeTypeImageBmp1;
|
||||
extern NSString *const OWSMimeTypeImageBmp2;
|
||||
extern NSString *const OWSMimeTypeOversizeTextMessage;
|
||||
extern NSString *const OWSMimeTypeUnknownForTests;
|
||||
|
||||
|
||||
@ -18,6 +18,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
NSString *const OWSMimeTypeApplicationOctetStream = @"application/octet-stream";
|
||||
NSString *const OWSMimeTypeImagePng = @"image/png";
|
||||
NSString *const OWSMimeTypeImageJpeg = @"image/jpeg";
|
||||
NSString *const OWSMimeTypeImageGif = @"image/gif";
|
||||
NSString *const OWSMimeTypeImageTiff1 = @"image/tiff";
|
||||
NSString *const OWSMimeTypeImageTiff2 = @"image/x-tiff";
|
||||
NSString *const OWSMimeTypeImageBmp1 = @"image/bmp";
|
||||
NSString *const OWSMimeTypeImageBmp2 = @"image/x-windows-bmp";
|
||||
NSString *const OWSMimeTypeOversizeTextMessage = @"text/x-signal-plain";
|
||||
NSString *const OWSMimeTypeUnknownForTests = @"unknown/mimetype";
|
||||
NSString *const OWSMimeTypeApplicationZip = @"application/zip";
|
||||
@ -76,7 +81,7 @@ NSString *const kSyncMessageFileExtension = @"bin";
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
result = @{
|
||||
@"image/jpeg" : @"jpeg",
|
||||
OWSMimeTypeImageJpeg : @"jpeg",
|
||||
@"image/pjpeg" : @"jpeg",
|
||||
OWSMimeTypeImagePng : @"png",
|
||||
@"image/tiff" : @"tif",
|
||||
@ -93,7 +98,7 @@ NSString *const kSyncMessageFileExtension = @"bin";
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
result = @{
|
||||
@"image/gif" : @"gif",
|
||||
OWSMimeTypeImageGif : @"gif",
|
||||
};
|
||||
});
|
||||
return result;
|
||||
@ -183,7 +188,7 @@ NSString *const kSyncMessageFileExtension = @"bin";
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
result = @{
|
||||
@"gif" : @"image/gif",
|
||||
@"gif" : OWSMimeTypeImageGif,
|
||||
};
|
||||
});
|
||||
return result;
|
||||
|
||||
@ -1,10 +1,14 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
@interface NSData (Image)
|
||||
|
||||
// If mimeType is non-nil, we ensure that the magic numbers agree with the
|
||||
// mimeType.
|
||||
+ (BOOL)ows_isValidImageAtPath:(NSString *)filePath;
|
||||
+ (BOOL)ows_isValidImageAtPath:(NSString *)filePath mimeType:(nullable NSString *)mimeType;
|
||||
- (BOOL)ows_isValidImage;
|
||||
- (BOOL)ows_isValidImageWithMimeType:(nullable NSString *)mimeType;
|
||||
|
||||
@end
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSData+Image.h"
|
||||
#import "MIMETypeUtil.h"
|
||||
|
||||
typedef NS_ENUM(NSInteger, ImageFormat) {
|
||||
ImageFormat_Unknown,
|
||||
@ -16,6 +17,16 @@ typedef NS_ENUM(NSInteger, ImageFormat) {
|
||||
@implementation NSData (Image)
|
||||
|
||||
+ (BOOL)ows_isValidImageAtPath:(NSString *)filePath
|
||||
{
|
||||
return [self ows_isValidImageAtPath:filePath mimeType:nil];
|
||||
}
|
||||
|
||||
- (BOOL)ows_isValidImage
|
||||
{
|
||||
return [self ows_isValidImageWithMimeType:nil];
|
||||
}
|
||||
|
||||
+ (BOOL)ows_isValidImageAtPath:(NSString *)filePath mimeType:(nullable NSString *)mimeType
|
||||
{
|
||||
NSError *error = nil;
|
||||
NSData *data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error];
|
||||
@ -23,22 +34,37 @@ typedef NS_ENUM(NSInteger, ImageFormat) {
|
||||
DDLogError(@"%@ could not read image data: %@", self.logTag, error);
|
||||
}
|
||||
|
||||
return [data ows_isValidImage];
|
||||
return [data ows_isValidImageWithMimeType:mimeType];
|
||||
}
|
||||
|
||||
- (BOOL)ows_isValidImage
|
||||
- (BOOL)ows_isValidImageWithMimeType:(nullable NSString *)mimeType
|
||||
{
|
||||
// Don't trust the file extension; iOS (e.g. UIKit, Core Graphics) will happily
|
||||
// load a .gif with a .png file extension.
|
||||
//
|
||||
// Instead, use the "magic numbers" in the file data to determine the image format.
|
||||
//
|
||||
// If the image has a declared MIME type, ensure that agrees with the
|
||||
// deduced image format.
|
||||
ImageFormat imageFormat = [self ows_guessImageFormat];
|
||||
if (imageFormat == ImageFormat_Gif) {
|
||||
return [self ows_hasValidGifSize];
|
||||
} else if (imageFormat == ImageFormat_Unknown) {
|
||||
return NO;
|
||||
} else {
|
||||
return YES;
|
||||
switch (imageFormat) {
|
||||
case ImageFormat_Unknown:
|
||||
return NO;
|
||||
case ImageFormat_Png:
|
||||
return (mimeType == nil || [mimeType isEqualToString:OWSMimeTypeImagePng]);
|
||||
case ImageFormat_Gif:
|
||||
if (![self ows_hasValidGifSize]) {
|
||||
return NO;
|
||||
}
|
||||
return (mimeType == nil || [mimeType isEqualToString:OWSMimeTypeImageGif]);
|
||||
case ImageFormat_Tiff:
|
||||
return (mimeType == nil || [mimeType isEqualToString:OWSMimeTypeImageTiff1] ||
|
||||
[mimeType isEqualToString:OWSMimeTypeImageTiff2]);
|
||||
case ImageFormat_Jpeg:
|
||||
return (mimeType == nil || [mimeType isEqualToString:OWSMimeTypeImageJpeg]);
|
||||
case ImageFormat_Bmp:
|
||||
return (mimeType == nil || [mimeType isEqualToString:OWSMimeTypeImageBmp1] ||
|
||||
[mimeType isEqualToString:OWSMimeTypeImageBmp2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user