Respond to CR.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-08-30 09:58:02 -04:00
parent ef21c6d50c
commit cc048b3971
14 changed files with 42 additions and 89 deletions

View File

@ -34,7 +34,6 @@
345671011E89A5F1006EE662 /* ThreadUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 345671001E89A5F1006EE662 /* ThreadUtil.m */; };
3456710A1E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m */; };
346B66311F4E29B200E5122F /* CropScaleImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346B66301F4E29B200E5122F /* CropScaleImageViewController.swift */; };
346B66381F55E24900E5122F /* NSData+Image.m in Sources */ = {isa = PBXBuildFile; fileRef = 346B66371F55E24900E5122F /* NSData+Image.m */; };
3471B1DA1EB7C63600F6AEC8 /* NewNonContactConversationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3471B1D91EB7C63600F6AEC8 /* NewNonContactConversationViewController.m */; };
3472229F1EB22FFE00E53955 /* AddToGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3472229E1EB22FFE00E53955 /* AddToGroupViewController.m */; };
348F2EAE1F0D21BC00D4ECE0 /* DeviceSleepManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 348F2EAD1F0D21BC00D4ECE0 /* DeviceSleepManager.swift */; };
@ -446,8 +445,6 @@
345671081E8A9F5D006EE662 /* TSGenericAttachmentAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSGenericAttachmentAdapter.h; sourceTree = "<group>"; };
345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSGenericAttachmentAdapter.m; sourceTree = "<group>"; };
346B66301F4E29B200E5122F /* CropScaleImageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CropScaleImageViewController.swift; sourceTree = "<group>"; };
346B66361F55E24900E5122F /* NSData+Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Image.h"; sourceTree = "<group>"; };
346B66371F55E24900E5122F /* NSData+Image.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Image.m"; sourceTree = "<group>"; };
3471B1D81EB7C63600F6AEC8 /* NewNonContactConversationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewNonContactConversationViewController.h; sourceTree = "<group>"; };
3471B1D91EB7C63600F6AEC8 /* NewNonContactConversationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NewNonContactConversationViewController.m; sourceTree = "<group>"; };
3472229D1EB22FFE00E53955 /* AddToGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToGroupViewController.h; sourceTree = "<group>"; };
@ -1426,8 +1423,6 @@
76EB04EA18170B33006006FC /* FunctionalUtil.h */,
76EB04EB18170B33006006FC /* FunctionalUtil.m */,
455AC69A1F4F79E500134004 /* ImageCache.swift */,
346B66361F55E24900E5122F /* NSData+Image.h */,
346B66371F55E24900E5122F /* NSData+Image.m */,
B62F5E0E1C2980B4000D370C /* NSData+ows_StripToken.h */,
B62F5E0F1C2980B4000D370C /* NSData+ows_StripToken.m */,
76EB04EC18170B33006006FC /* NumberUtil.h */,
@ -2241,7 +2236,6 @@
45794E861E00620000066731 /* CallUIAdapter.swift in Sources */,
4585C4681ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift in Sources */,
FCFA64B71A24F6730007FB87 /* UIFont+OWS.m in Sources */,
346B66381F55E24900E5122F /* NSData+Image.m in Sources */,
B6B9ECFC198B31BA00C620D3 /* PushManager.m in Sources */,
45DF5DF21DDB843F00C936C7 /* CompareSafetyNumbersActivity.swift in Sources */,
458DE9D91DEE7B360071BB03 /* OWSWebRTCDataProtos.pb.m in Sources */,

View File

@ -6,6 +6,7 @@
#import "NumberUtil.h"
#import "UIDevice+TSHardwareVersion.h"
#import <ImageIO/ImageIO.h>
#import <SignalServiceKit/NSData+Image.h>
@implementation JSQMediaItem (OWS)
@ -42,6 +43,10 @@
{
OWSAssert(imageURL);
if (![NSData ows_isValidImageAtPath:imageURL.path]) {
return CGSizeZero;
}
// With CGImageSource we avoid loading the whole image into memory.
CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)imageURL, NULL);
if (!source) {

View File

@ -6,13 +6,13 @@
#import "AttachmentUploadView.h"
#import "FLAnimatedImage.h"
#import "JSQMediaItem+OWS.h"
#import "NSData+Image.h"
#import "TSAttachmentStream.h"
#import "UIColor+OWS.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import <JSQMessagesViewController/JSQMessagesMediaViewBubbleImageMasker.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <SignalServiceKit/MIMETypeUtil.h>
#import <SignalServiceKit/NSData+Image.h>
NS_ASSUME_NONNULL_BEGIN
@ -28,8 +28,6 @@ NS_ASSUME_NONNULL_BEGIN
// See comments on OWSMessageMediaAdapter.
@property (nonatomic, nullable, weak) id lastPresentingCell;
@property (nonatomic) NSNumber *isImageValid;
@end
#pragma mark -
@ -99,21 +97,10 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - JSQMessageMediaData protocol
- (NSNumber *)isImageValid
{
if (!_isImageValid) {
_isImageValid = @([NSData isValidImageAtPath:[self.attachment mediaURL].path]);
}
return _isImageValid;
}
- (UIView *)mediaView {
OWSAssert([NSThread isMainThread]);
if (self.cachedImageView == nil) {
if (![self isImageValid]) {
return nil;
}
// Use Flipboard FLAnimatedImage library to display gifs
NSData *fileData = [NSData dataWithContentsOfURL:[self.attachment mediaURL]];
if (!fileData) {
@ -122,6 +109,9 @@ NS_ASSUME_NONNULL_BEGIN
view.backgroundColor = [UIColor colorWithWhite:0.85f alpha:1.f];
return view;
}
if (![fileData ows_isValidImage]) {
return nil;
}
FLAnimatedImage *animatedGif = [FLAnimatedImage animatedImageWithGIFData:fileData];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = animatedGif;

View File

@ -7,6 +7,7 @@
#import "NSString+OWS.h"
#import "Signal-Swift.h"
#import <SignalServiceKit/Cryptography.h>
#import <SignalServiceKit/NSData+Image.h>
#import <SignalServiceKit/NSData+hexString.h>
#import <SignalServiceKit/NSDate+OWS.h>
#import <SignalServiceKit/OWSMessageSender.h>
@ -1333,7 +1334,11 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
{
OWSAssert(filename.length > 0);
UIImage *_Nullable image = [UIImage imageWithData:[self loadProfileDataWithFilename:filename]];
NSData *data = [self loadProfileDataWithFilename:filename];
if (![data ows_isValidImage]) {
return nil;
}
UIImage *_Nullable image = [UIImage imageWithData:data];
return image;
}

View File

@ -10,7 +10,6 @@
#import "Environment.h"
#import "FLAnimatedImage.h"
#import "FingerprintViewController.h"
#import "NSData+Image.h"
#import "NotificationsManager.h"
#import "OWSAnyTouchGestureRecognizer.h"
#import "OWSAudioAttachmentPlayer.h"
@ -49,6 +48,7 @@
#import <SignalServiceKit/Cryptography.h>
#import <SignalServiceKit/MIMETypeUtil.h>
#import <SignalServiceKit/NSData+Base64.h>
#import <SignalServiceKit/NSData+Image.h>
#import <SignalServiceKit/NSDate+millisecondTimeStamp.h>
#import <SignalServiceKit/NSTimer+OWS.h>
#import <SignalServiceKit/OWSAcknowledgeMessageDeliveryRequest.h>

View File

@ -172,7 +172,7 @@ class AttachmentApprovalViewController: OWSViewController, OWSAudioAttachmentPla
private func createAnimatedPreview(attachmentPreviewView: UIView) {
let data = attachment.data
guard (data as NSData).isValidImage() else {
guard (data as NSData).ows_isValidImage() else {
return
}

View File

@ -5,13 +5,13 @@
#import "FullImageViewController.h"
#import "AttachmentSharing.h"
#import "FLAnimatedImage.h"
#import "NSData+Image.h"
#import "TSAnimatedAdapter.h"
#import "TSMessageAdapter.h"
#import "TSPhotoAdapter.h"
#import "UIColor+OWS.h"
#import "UIUtil.h"
#import "UIView+OWS.h"
#import <SignalServiceKit/NSData+Image.h>
NS_ASSUME_NONNULL_BEGIN
@ -169,7 +169,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)initializeImageView {
if (self.isAnimated) {
if ([self.fileData isValidImage]) {
if ([self.fileData ows_isValidImage]) {
// Present the animated image using Flipboard/FLAnimatedImage
FLAnimatedImage *animatedGif = [FLAnimatedImage animatedImageWithGIFData:self.fileData];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];

View File

@ -1,9 +1,12 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MIMETypeUtil.h"
#import "UIColor+OWS.h"
#import "UIFont+OWS.h"
#import "UIImage+contentTypes.h"
#import "UIImage+normalizeImage.h"
typedef void (^completionBlock)(void);

View File

@ -4,6 +4,7 @@
#import "TSAttachmentStream.h"
#import "MIMETypeUtil.h"
#import "NSData+Image.h"
#import "TSAttachmentPointer.h"
#import <AVFoundation/AVFoundation.h>
#import <ImageIO/ImageIO.h>
@ -257,6 +258,9 @@ NS_ASSUME_NONNULL_BEGIN
if (!mediaUrl) {
return nil;
}
if (![NSData ows_isValidImageAtPath:mediaUrl.path]) {
return nil;
}
return [UIImage imageWithData:[NSData dataWithContentsOfURL:mediaUrl]];
} else {
return nil;
@ -314,6 +318,9 @@ NS_ASSUME_NONNULL_BEGIN
if (!mediaUrl) {
return CGSizeZero;
}
if (![NSData ows_isValidImageAtPath:mediaUrl.path]) {
return CGSizeZero;
}
// With CGImageSource we avoid loading the whole image into memory.
CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)mediaUrl, NULL);

View File

@ -4,7 +4,6 @@
#import "MIMETypeUtil.h"
#if TARGET_OS_IPHONE
#import "UIImage+contentTypes.h"
#import <MobileCoreServices/MobileCoreServices.h>
#else
#import <CoreServices/CoreServices.h>

View File

@ -6,7 +6,7 @@
@interface NSData (Image)
+ (BOOL)isValidImageAtPath:(NSString *)filePath;
- (BOOL)isValidImage;
+ (BOOL)ows_isValidImageAtPath:(NSString *)filePath;
- (BOOL)ows_isValidImage;
@end

View File

@ -15,7 +15,7 @@ typedef NS_ENUM(NSInteger, ImageFormat) {
@implementation NSData (Image)
+ (BOOL)isValidImageAtPath:(NSString *)filePath
+ (BOOL)ows_isValidImageAtPath:(NSString *)filePath
{
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfFile:filePath options:NSMappedRead error:&error];
@ -23,18 +23,18 @@ typedef NS_ENUM(NSInteger, ImageFormat) {
DDLogError(@"%@ could not read image data: %@", self.tag, error);
}
return [data isValidImage];
return [data ows_isValidImage];
}
- (BOOL)isValidImage
- (BOOL)ows_isValidImage
{
// 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.
ImageFormat imageFormat = [self guessImageFormat];
ImageFormat imageFormat = [self ows_guessImageFormat];
if (imageFormat == ImageFormat_Gif) {
return [self hasValidGifSize];
return [self ows_hasValidGifSize];
} else if (imageFormat == ImageFormat_Unknown) {
return NO;
} else {
@ -42,7 +42,7 @@ typedef NS_ENUM(NSInteger, ImageFormat) {
}
}
- (ImageFormat)guessImageFormat
- (ImageFormat)ows_guessImageFormat
{
const NSUInteger kTwoBytesLength = 2;
if (self.length < kTwoBytesLength) {
@ -74,7 +74,7 @@ typedef NS_ENUM(NSInteger, ImageFormat) {
return ImageFormat_Unknown;
}
+ (BOOL)areByteArraysEqual:(NSUInteger)length left:(unsigned char *)left right:(unsigned char *)right
+ (BOOL)ows_areByteArraysEqual:(NSUInteger)length left:(unsigned char *)left right:(unsigned char *)right
{
for (NSUInteger i = 0; i < length; i++) {
if (left[i] != right[i]) {
@ -88,7 +88,7 @@ typedef NS_ENUM(NSInteger, ImageFormat) {
//
// See: https://blog.flanker017.me/cve-2017-2416-gif-remote-exec/
// See: https://www.w3.org/Graphics/GIF/spec-gif89a.txt
- (BOOL)hasValidGifSize
- (BOOL)ows_hasValidGifSize
{
const NSUInteger kSignatureLength = 3;
const NSUInteger kVersionLength = 3;
@ -110,8 +110,8 @@ typedef NS_ENUM(NSInteger, ImageFormat) {
unsigned char kGif89APrefix[kPrefixLength] = {
0x47, 0x49, 0x46, 0x38, 0x39, 0x61,
};
if (![NSData areByteArraysEqual:kPrefixLength left:bytes right:kGif87APrefix]
&& ![NSData areByteArraysEqual:kPrefixLength left:bytes right:kGif89APrefix]) {
if (![NSData ows_areByteArraysEqual:kPrefixLength left:bytes right:kGif87APrefix]
&& ![NSData ows_areByteArraysEqual:kPrefixLength left:bytes right:kGif89APrefix]) {
return NO;
}
NSUInteger width = ((NSUInteger)bytes[kPrefixLength + 0]) | (((NSUInteger)bytes[kPrefixLength + 1] << 8));

View File

@ -1,16 +0,0 @@
//
// UIImage+contentTypes.h
// Signal
//
// Created by Frederic Jacobs on 21/12/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIImage (contentTypes)
- (NSString *)contentType;
- (BOOL)isSupportedImageType;
@end

View File

@ -1,34 +0,0 @@
// Created by Frederic Jacobs on 21/12/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
#import "MIMETypeUtil.h"
#import "UIImage+contentTypes.h"
@implementation UIImage (contentTypes)
- (NSString *)contentType {
uint8_t c;
[UIImagePNGRepresentation(self) getBytes:&c length:1];
switch (c) {
case 0xFF:
return @"image/jpeg";
case 0x89:
return OWSMimeTypeImagePng;
case 0x47:
return @"image/gif";
case 0x49:
break;
case 0x42:
return @"image/bmp";
case 0x4D:
return @"image/tiff";
}
return nil;
}
- (BOOL)isSupportedImageType {
return ([self contentType] ? YES : NO);
}
@end