Merge branch 'charlesmchen/honorAttachmentFilenames'

pull/1/head
Matthew Chen 8 years ago
commit 238fd0d9f1

@ -39,11 +39,15 @@ message Content {
message CallMessage { message CallMessage {
message Offer { message Offer {
optional uint64 id = 1; optional uint64 id = 1;
// We've renamed the description field on iOS to avoid
// conflicts with [NSObject description].
optional string sessionDescription = 2; optional string sessionDescription = 2;
} }
message Answer { message Answer {
optional uint64 id = 1; optional uint64 id = 1;
// We've renamed the description field on iOS to avoid
// conflicts with [NSObject description].
optional string sessionDescription = 2; optional string sessionDescription = 2;
} }
@ -134,14 +138,16 @@ message AttachmentPointer {
optional uint32 size = 4; optional uint32 size = 4;
optional bytes thumbnail = 5; optional bytes thumbnail = 5;
optional bytes digest = 6; optional bytes digest = 6;
optional string fileName = 7;
} }
message GroupContext { message GroupContext {
enum Type { enum Type {
UNKNOWN = 0; UNKNOWN = 0;
UPDATE = 1; UPDATE = 1;
DELIVER = 2; DELIVER = 2;
QUIT = 3; QUIT = 3;
REQUEST_INFO = 4;
} }
optional bytes id = 1; optional bytes id = 1;
optional Type type = 2; optional Type type = 2;

@ -75,7 +75,8 @@ NS_ASSUME_NONNULL_BEGIN
key:attachmentProto.key key:attachmentProto.key
digest:digest digest:digest
contentType:attachmentProto.contentType contentType:attachmentProto.contentType
relay:relay]; relay:relay
filename:attachmentProto.fileName];
[attachmentIds addObject:pointer.uniqueId]; [attachmentIds addObject:pointer.uniqueId];

@ -21,9 +21,11 @@ typedef NS_ENUM(NSUInteger, TSAttachmentPointerState) {
key:(NSData *)key key:(NSData *)key
digest:(nullable NSData *)digest digest:(nullable NSData *)digest
contentType:(NSString *)contentType contentType:(NSString *)contentType
relay:(NSString *)relay NS_DESIGNATED_INITIALIZER; relay:(NSString *)relay
filename:(nullable NSString *)filename NS_DESIGNATED_INITIALIZER;
@property (nonatomic, readonly) NSString *relay; @property (nonatomic, readonly) NSString *relay;
@property (nonatomic, readonly, nullable) NSString *filename;
@property (atomic) TSAttachmentPointerState state; @property (atomic) TSAttachmentPointerState state;
// Though now required, `digest` may be null for pre-existing records or from // Though now required, `digest` may be null for pre-existing records or from

@ -30,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN
digest:(nullable NSData *)digest digest:(nullable NSData *)digest
contentType:(NSString *)contentType contentType:(NSString *)contentType
relay:(NSString *)relay relay:(NSString *)relay
filename:(nullable NSString *)filename
{ {
self = [super initWithServerId:serverId encryptionKey:key contentType:contentType]; self = [super initWithServerId:serverId encryptionKey:key contentType:contentType];
if (!self) { if (!self) {
@ -39,6 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
_digest = digest; _digest = digest;
_state = TSAttachmentPointerStateEnqueued; _state = TSAttachmentPointerStateEnqueued;
_relay = relay; _relay = relay;
_filename = filename;
return self; return self;
} }

@ -24,6 +24,8 @@ NS_ASSUME_NONNULL_BEGIN
// This only applies for attachments being uploaded. // This only applies for attachments being uploaded.
@property (atomic) BOOL isUploaded; @property (atomic) BOOL isUploaded;
@property (nonatomic, readonly, nullable) NSString *filename;
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
- (nullable UIImage *)image; - (nullable UIImage *)image;
#endif #endif

@ -42,6 +42,7 @@ NS_ASSUME_NONNULL_BEGIN
// state, but this constructor is used only for new incoming // state, but this constructor is used only for new incoming
// attachments which don't need to be uploaded. // attachments which don't need to be uploaded.
_isUploaded = YES; _isUploaded = YES;
_filename = pointer.filename;
return self; return self;
} }
@ -115,6 +116,7 @@ NS_ASSUME_NONNULL_BEGIN
{ {
return [MIMETypeUtil filePathForAttachment:self.uniqueId return [MIMETypeUtil filePathForAttachment:self.uniqueId
ofMIMEType:self.contentType ofMIMEType:self.contentType
filename:self.filename
inFolder:[[self class] attachmentsFolder]]; inFolder:[[self class] attachmentsFolder]];
} }

@ -1,4 +1,6 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved. //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSSyncContactsMessage.h" #import "OWSSyncContactsMessage.h"
#import "Contact.h" #import "Contact.h"
@ -39,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
} }
OWSSignalServiceProtosAttachmentPointer *attachmentProto = OWSSignalServiceProtosAttachmentPointer *attachmentProto =
[self buildAttachmentProtoForAttachmentId:self.attachmentIds[0]]; [self buildAttachmentProtoForAttachmentId:self.attachmentIds[0] filename:nil];
OWSSignalServiceProtosSyncMessageContactsBuilder *contactsBuilder = OWSSignalServiceProtosSyncMessageContactsBuilder *contactsBuilder =
[OWSSignalServiceProtosSyncMessageContactsBuilder new]; [OWSSignalServiceProtosSyncMessageContactsBuilder new];

@ -1,4 +1,6 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved. //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSSyncGroupsMessage.h" #import "OWSSyncGroupsMessage.h"
#import "NSDate+millisecondTimeStamp.h" #import "NSDate+millisecondTimeStamp.h"
@ -25,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
(unsigned long)self.attachmentIds.count); (unsigned long)self.attachmentIds.count);
} }
OWSSignalServiceProtosAttachmentPointer *attachmentProto = OWSSignalServiceProtosAttachmentPointer *attachmentProto =
[self buildAttachmentProtoForAttachmentId:self.attachmentIds[0]]; [self buildAttachmentProtoForAttachmentId:self.attachmentIds[0] filename:nil];
OWSSignalServiceProtosSyncMessageGroupsBuilder *groupsBuilder = OWSSignalServiceProtosSyncMessageGroupsBuilder *groupsBuilder =
[OWSSignalServiceProtosSyncMessageGroupsBuilder new]; [OWSSignalServiceProtosSyncMessageGroupsBuilder new];

@ -128,7 +128,6 @@ static const NSUInteger OWSMessageSchemaVersion = 3;
} }
if (!_attachmentIds) { if (!_attachmentIds) {
// previously allowed nil _attachmentIds
_attachmentIds = [NSMutableArray new]; _attachmentIds = [NSMutableArray new];
} }

@ -57,6 +57,8 @@ typedef NS_ENUM(NSInteger, TSOutgoingMessageState) {
@property BOOL hasSyncedTranscript; @property BOOL hasSyncedTranscript;
@property NSString *customMessage; @property NSString *customMessage;
@property (atomic, readonly) NSString *mostRecentFailureText; @property (atomic, readonly) NSString *mostRecentFailureText;
// A map of attachment id-to-filename.
@property (nonatomic, readonly) NSMutableDictionary<NSString *, NSString *> *attachmentFilenameMap;
/** /**
* Whether the message should be serialized as a modern aka Content, or the old style legacy message. * Whether the message should be serialized as a modern aka Content, or the old style legacy message.
@ -94,10 +96,14 @@ typedef NS_ENUM(NSInteger, TSOutgoingMessageState) {
* @param attachmentId * @param attachmentId
* id of an AttachmentStream containing the meta data used when populating the attachment proto * id of an AttachmentStream containing the meta data used when populating the attachment proto
* *
* @param filename
* optional filename of the attachment.
*
* @return * @return
* An attachment pointer protobuf suitable for including in various container protobuf builders * An attachment pointer protobuf suitable for including in various container protobuf builders
*/ */
- (OWSSignalServiceProtosAttachmentPointer *)buildAttachmentProtoForAttachmentId:(NSString *)attachmentId; - (OWSSignalServiceProtosAttachmentPointer *)buildAttachmentProtoForAttachmentId:(NSString *)attachmentId
filename:(nullable NSString *)filename;
@end @end

@ -15,7 +15,13 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithCoder:(NSCoder *)coder - (instancetype)initWithCoder:(NSCoder *)coder
{ {
return [super initWithCoder:coder]; self = [super initWithCoder:coder];
if (self) {
if (!_attachmentFilenameMap) {
_attachmentFilenameMap = [NSMutableDictionary new];
}
}
return self;
} }
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initWithTimestamp:(uint64_t)timestamp
@ -86,6 +92,7 @@ NS_ASSUME_NONNULL_BEGIN
} else { } else {
self.groupMetaMessage = TSGroupMessageNone; self.groupMetaMessage = TSGroupMessageNone;
} }
_attachmentFilenameMap = [NSMutableDictionary new];
OWSAssert(self.receivedAtDate); OWSAssert(self.receivedAtDate);
@ -142,7 +149,8 @@ NS_ASSUME_NONNULL_BEGIN
case TSGroupMessageNew: { case TSGroupMessageNew: {
if (gThread.groupModel.groupImage != nil && self.attachmentIds.count == 1) { if (gThread.groupModel.groupImage != nil && self.attachmentIds.count == 1) {
attachmentWasGroupAvatar = YES; attachmentWasGroupAvatar = YES;
[groupBuilder setAvatar:[self buildAttachmentProtoForAttachmentId:self.attachmentIds[0]]]; [groupBuilder
setAvatar:[self buildAttachmentProtoForAttachmentId:self.attachmentIds[0] filename:nil]];
} }
[groupBuilder setMembersArray:gThread.groupModel.groupMemberIds]; [groupBuilder setMembersArray:gThread.groupModel.groupMemberIds];
@ -160,7 +168,8 @@ NS_ASSUME_NONNULL_BEGIN
if (!attachmentWasGroupAvatar) { if (!attachmentWasGroupAvatar) {
NSMutableArray *attachments = [NSMutableArray new]; NSMutableArray *attachments = [NSMutableArray new];
for (NSString *attachmentId in self.attachmentIds) { for (NSString *attachmentId in self.attachmentIds) {
[attachments addObject:[self buildAttachmentProtoForAttachmentId:attachmentId]]; NSString *filename = self.attachmentFilenameMap[attachmentId];
[attachments addObject:[self buildAttachmentProtoForAttachmentId:attachmentId filename:filename]];
} }
[builder setAttachmentsArray:attachments]; [builder setAttachmentsArray:attachments];
} }
@ -191,7 +200,10 @@ NS_ASSUME_NONNULL_BEGIN
} }
- (OWSSignalServiceProtosAttachmentPointer *)buildAttachmentProtoForAttachmentId:(NSString *)attachmentId - (OWSSignalServiceProtosAttachmentPointer *)buildAttachmentProtoForAttachmentId:(NSString *)attachmentId
filename:(nullable NSString *)filename
{ {
OWSAssert(attachmentId.length > 0);
TSAttachment *attachment = [TSAttachmentStream fetchObjectWithUniqueID:attachmentId]; TSAttachment *attachment = [TSAttachmentStream fetchObjectWithUniqueID:attachmentId];
if (![attachment isKindOfClass:[TSAttachmentStream class]]) { if (![attachment isKindOfClass:[TSAttachmentStream class]]) {
DDLogError(@"Unexpected type for attachment builder: %@", attachment); DDLogError(@"Unexpected type for attachment builder: %@", attachment);
@ -202,6 +214,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSSignalServiceProtosAttachmentPointerBuilder *builder = [OWSSignalServiceProtosAttachmentPointerBuilder new]; OWSSignalServiceProtosAttachmentPointerBuilder *builder = [OWSSignalServiceProtosAttachmentPointerBuilder new];
[builder setId:attachmentStream.serverId]; [builder setId:attachmentStream.serverId];
[builder setContentType:attachmentStream.contentType]; [builder setContentType:attachmentStream.contentType];
[builder setFileName:filename];
[builder setKey:attachmentStream.encryptionKey]; [builder setKey:attachmentStream.encryptionKey];
[builder setDigest:attachmentStream.digest]; [builder setDigest:attachmentStream.digest];

@ -1,5 +1,6 @@
// Created by Michael Kirk on 12/1/16. //
// Copyright © 2016 Open Whisper Systems. All rights reserved. // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSCallAnswerMessage.h" #import "OWSCallAnswerMessage.h"
#import "OWSSignalServiceProtos.pb.h" #import "OWSSignalServiceProtos.pb.h"

@ -1,5 +1,6 @@
// Created by Michael Kirk on 12/1/16. //
// Copyright © 2016 Open Whisper Systems. All rights reserved. // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSCallOfferMessage.h" #import "OWSCallOfferMessage.h"
#import "OWSSignalServiceProtos.pb.h" #import "OWSSignalServiceProtos.pb.h"

@ -55,6 +55,7 @@ NS_SWIFT_NAME(MessageSender)
*/ */
- (void)sendAttachmentData:(NSData *)attachmentData - (void)sendAttachmentData:(NSData *)attachmentData
contentType:(NSString *)contentType contentType:(NSString *)contentType
filename:(nullable NSString *)filename
inMessage:(TSOutgoingMessage *)outgoingMessage inMessage:(TSOutgoingMessage *)outgoingMessage
success:(void (^)())successHandler success:(void (^)())successHandler
failure:(void (^)(NSError *error))failureHandler; failure:(void (^)(NSError *error))failureHandler;

@ -437,6 +437,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[self sendAttachmentData:attachmentData [self sendAttachmentData:attachmentData
contentType:contentType contentType:contentType
filename:nil
inMessage:message inMessage:message
success:successWithDeleteHandler success:successWithDeleteHandler
failure:failureWithDeleteHandler]; failure:failureWithDeleteHandler];
@ -444,6 +445,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
- (void)sendAttachmentData:(NSData *)data - (void)sendAttachmentData:(NSData *)data
contentType:(NSString *)contentType contentType:(NSString *)contentType
filename:(nullable NSString *)filename
inMessage:(TSOutgoingMessage *)message inMessage:(TSOutgoingMessage *)message
success:(void (^)())successHandler success:(void (^)())successHandler
failure:(void (^)(NSError *error))failureHandler failure:(void (^)(NSError *error))failureHandler
@ -467,6 +469,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[attachmentStream save]; [attachmentStream save];
[message.attachmentIds addObject:attachmentStream.uniqueId]; [message.attachmentIds addObject:attachmentStream.uniqueId];
if (filename) {
message.attachmentFilenameMap[attachmentStream.uniqueId] = filename;
}
[message save]; [message save];
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{

@ -1,4 +1,6 @@
// Generated by the protocol buffer compiler. DO NOT EDIT! //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <ProtocolBuffers/ProtocolBuffers.h> #import <ProtocolBuffers/ProtocolBuffers.h>
@ -128,6 +130,7 @@ typedef NS_ENUM(SInt32, OWSSignalServiceProtosGroupContextType) {
OWSSignalServiceProtosGroupContextTypeUpdate = 1, OWSSignalServiceProtosGroupContextTypeUpdate = 1,
OWSSignalServiceProtosGroupContextTypeDeliver = 2, OWSSignalServiceProtosGroupContextTypeDeliver = 2,
OWSSignalServiceProtosGroupContextTypeQuit = 3, OWSSignalServiceProtosGroupContextTypeQuit = 3,
OWSSignalServiceProtosGroupContextTypeRequestInfo = 4,
}; };
BOOL OWSSignalServiceProtosGroupContextTypeIsValidValue(OWSSignalServiceProtosGroupContextType value); BOOL OWSSignalServiceProtosGroupContextTypeIsValidValue(OWSSignalServiceProtosGroupContextType value);
@ -1278,16 +1281,19 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
#define AttachmentPointer_size @"size" #define AttachmentPointer_size @"size"
#define AttachmentPointer_thumbnail @"thumbnail" #define AttachmentPointer_thumbnail @"thumbnail"
#define AttachmentPointer_digest @"digest" #define AttachmentPointer_digest @"digest"
#define AttachmentPointer_fileName @"fileName"
@interface OWSSignalServiceProtosAttachmentPointer : PBGeneratedMessage<GeneratedMessageProtocol> { @interface OWSSignalServiceProtosAttachmentPointer : PBGeneratedMessage<GeneratedMessageProtocol> {
@private @private
BOOL hasId_:1; BOOL hasId_:1;
BOOL hasContentType_:1; BOOL hasContentType_:1;
BOOL hasFileName_:1;
BOOL hasKey_:1; BOOL hasKey_:1;
BOOL hasThumbnail_:1; BOOL hasThumbnail_:1;
BOOL hasDigest_:1; BOOL hasDigest_:1;
BOOL hasSize_:1; BOOL hasSize_:1;
UInt64 id; UInt64 id;
NSString* contentType; NSString* contentType;
NSString* fileName;
NSData* key; NSData* key;
NSData* thumbnail; NSData* thumbnail;
NSData* digest; NSData* digest;
@ -1299,12 +1305,14 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
- (BOOL) hasSize; - (BOOL) hasSize;
- (BOOL) hasThumbnail; - (BOOL) hasThumbnail;
- (BOOL) hasDigest; - (BOOL) hasDigest;
- (BOOL) hasFileName;
@property (readonly) UInt64 id; @property (readonly) UInt64 id;
@property (readonly, strong) NSString* contentType; @property (readonly, strong) NSString* contentType;
@property (readonly, strong) NSData* key; @property (readonly, strong) NSData* key;
@property (readonly) UInt32 size; @property (readonly) UInt32 size;
@property (readonly, strong) NSData* thumbnail; @property (readonly, strong) NSData* thumbnail;
@property (readonly, strong) NSData* digest; @property (readonly, strong) NSData* digest;
@property (readonly, strong) NSString* fileName;
+ (instancetype) defaultInstance; + (instancetype) defaultInstance;
- (instancetype) defaultInstance; - (instancetype) defaultInstance;
@ -1370,6 +1378,11 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
- (NSData*) digest; - (NSData*) digest;
- (OWSSignalServiceProtosAttachmentPointerBuilder*) setDigest:(NSData*) value; - (OWSSignalServiceProtosAttachmentPointerBuilder*) setDigest:(NSData*) value;
- (OWSSignalServiceProtosAttachmentPointerBuilder*) clearDigest; - (OWSSignalServiceProtosAttachmentPointerBuilder*) clearDigest;
- (BOOL) hasFileName;
- (NSString*) fileName;
- (OWSSignalServiceProtosAttachmentPointerBuilder*) setFileName:(NSString*) value;
- (OWSSignalServiceProtosAttachmentPointerBuilder*) clearFileName;
@end @end
#define GroupContext_id @"id" #define GroupContext_id @"id"

@ -1,4 +1,6 @@
// Generated by the protocol buffer compiler. DO NOT EDIT! //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSSignalServiceProtos.pb.h" #import "OWSSignalServiceProtos.pb.h"
// @@protoc_insertion_point(imports) // @@protoc_insertion_point(imports)
@ -5320,6 +5322,7 @@ static OWSSignalServiceProtosSyncMessageRead* defaultOWSSignalServiceProtosSyncM
@property UInt32 size; @property UInt32 size;
@property (strong) NSData* thumbnail; @property (strong) NSData* thumbnail;
@property (strong) NSData* digest; @property (strong) NSData* digest;
@property (strong) NSString* fileName;
@end @end
@implementation OWSSignalServiceProtosAttachmentPointer @implementation OWSSignalServiceProtosAttachmentPointer
@ -5366,6 +5369,13 @@ static OWSSignalServiceProtosSyncMessageRead* defaultOWSSignalServiceProtosSyncM
hasDigest_ = !!_value_; hasDigest_ = !!_value_;
} }
@synthesize digest; @synthesize digest;
- (BOOL) hasFileName {
return !!hasFileName_;
}
- (void) setHasFileName:(BOOL) _value_ {
hasFileName_ = !!_value_;
}
@synthesize fileName;
- (instancetype) init { - (instancetype) init {
if ((self = [super init])) { if ((self = [super init])) {
self.id = 0L; self.id = 0L;
@ -5374,6 +5384,7 @@ static OWSSignalServiceProtosSyncMessageRead* defaultOWSSignalServiceProtosSyncM
self.size = 0; self.size = 0;
self.thumbnail = [NSData data]; self.thumbnail = [NSData data];
self.digest = [NSData data]; self.digest = [NSData data];
self.fileName = @"";
} }
return self; return self;
} }
@ -5411,6 +5422,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt
if (self.hasDigest) { if (self.hasDigest) {
[output writeData:6 value:self.digest]; [output writeData:6 value:self.digest];
} }
if (self.hasFileName) {
[output writeString:7 value:self.fileName];
}
[self.unknownFields writeToCodedOutputStream:output]; [self.unknownFields writeToCodedOutputStream:output];
} }
- (SInt32) serializedSize { - (SInt32) serializedSize {
@ -5438,6 +5452,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt
if (self.hasDigest) { if (self.hasDigest) {
size_ += computeDataSize(6, self.digest); size_ += computeDataSize(6, self.digest);
} }
if (self.hasFileName) {
size_ += computeStringSize(7, self.fileName);
}
size_ += self.unknownFields.serializedSize; size_ += self.unknownFields.serializedSize;
memoizedSerializedSize = size_; memoizedSerializedSize = size_;
return size_; return size_;
@ -5491,6 +5508,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt
if (self.hasDigest) { if (self.hasDigest) {
[output appendFormat:@"%@%@: %@\n", indent, @"digest", self.digest]; [output appendFormat:@"%@%@: %@\n", indent, @"digest", self.digest];
} }
if (self.hasFileName) {
[output appendFormat:@"%@%@: %@\n", indent, @"fileName", self.fileName];
}
[self.unknownFields writeDescriptionTo:output withIndent:indent]; [self.unknownFields writeDescriptionTo:output withIndent:indent];
} }
- (void) storeInDictionary:(NSMutableDictionary *)dictionary { - (void) storeInDictionary:(NSMutableDictionary *)dictionary {
@ -5512,6 +5532,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt
if (self.hasDigest) { if (self.hasDigest) {
[dictionary setObject: self.digest forKey: @"digest"]; [dictionary setObject: self.digest forKey: @"digest"];
} }
if (self.hasFileName) {
[dictionary setObject: self.fileName forKey: @"fileName"];
}
[self.unknownFields storeInDictionary:dictionary]; [self.unknownFields storeInDictionary:dictionary];
} }
- (BOOL) isEqual:(id)other { - (BOOL) isEqual:(id)other {
@ -5535,6 +5558,8 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt
(!self.hasThumbnail || [self.thumbnail isEqual:otherMessage.thumbnail]) && (!self.hasThumbnail || [self.thumbnail isEqual:otherMessage.thumbnail]) &&
self.hasDigest == otherMessage.hasDigest && self.hasDigest == otherMessage.hasDigest &&
(!self.hasDigest || [self.digest isEqual:otherMessage.digest]) && (!self.hasDigest || [self.digest isEqual:otherMessage.digest]) &&
self.hasFileName == otherMessage.hasFileName &&
(!self.hasFileName || [self.fileName isEqual:otherMessage.fileName]) &&
(self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields])); (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
} }
- (NSUInteger) hash { - (NSUInteger) hash {
@ -5557,6 +5582,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt
if (self.hasDigest) { if (self.hasDigest) {
hashCode = hashCode * 31 + [self.digest hash]; hashCode = hashCode * 31 + [self.digest hash];
} }
if (self.hasFileName) {
hashCode = hashCode * 31 + [self.fileName hash];
}
hashCode = hashCode * 31 + [self.unknownFields hash]; hashCode = hashCode * 31 + [self.unknownFields hash];
return hashCode; return hashCode;
} }
@ -5618,6 +5646,9 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt
if (other.hasDigest) { if (other.hasDigest) {
[self setDigest:other.digest]; [self setDigest:other.digest];
} }
if (other.hasFileName) {
[self setFileName:other.fileName];
}
[self mergeUnknownFields:other.unknownFields]; [self mergeUnknownFields:other.unknownFields];
return self; return self;
} }
@ -5663,6 +5694,10 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt
[self setDigest:[input readData]]; [self setDigest:[input readData]];
break; break;
} }
case 58: {
[self setFileName:[input readString]];
break;
}
} }
} }
} }
@ -5762,6 +5797,22 @@ static OWSSignalServiceProtosAttachmentPointer* defaultOWSSignalServiceProtosAtt
resultAttachmentPointer.digest = [NSData data]; resultAttachmentPointer.digest = [NSData data];
return self; return self;
} }
- (BOOL) hasFileName {
return resultAttachmentPointer.hasFileName;
}
- (NSString*) fileName {
return resultAttachmentPointer.fileName;
}
- (OWSSignalServiceProtosAttachmentPointerBuilder*) setFileName:(NSString*) value {
resultAttachmentPointer.hasFileName = YES;
resultAttachmentPointer.fileName = value;
return self;
}
- (OWSSignalServiceProtosAttachmentPointerBuilder*) clearFileName {
resultAttachmentPointer.hasFileName = NO;
resultAttachmentPointer.fileName = @"";
return self;
}
@end @end
@interface OWSSignalServiceProtosGroupContext () @interface OWSSignalServiceProtosGroupContext ()
@ -6001,6 +6052,7 @@ BOOL OWSSignalServiceProtosGroupContextTypeIsValidValue(OWSSignalServiceProtosGr
case OWSSignalServiceProtosGroupContextTypeUpdate: case OWSSignalServiceProtosGroupContextTypeUpdate:
case OWSSignalServiceProtosGroupContextTypeDeliver: case OWSSignalServiceProtosGroupContextTypeDeliver:
case OWSSignalServiceProtosGroupContextTypeQuit: case OWSSignalServiceProtosGroupContextTypeQuit:
case OWSSignalServiceProtosGroupContextTypeRequestInfo:
return YES; return YES;
default: default:
return NO; return NO;
@ -6016,6 +6068,8 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
return @"OWSSignalServiceProtosGroupContextTypeDeliver"; return @"OWSSignalServiceProtosGroupContextTypeDeliver";
case OWSSignalServiceProtosGroupContextTypeQuit: case OWSSignalServiceProtosGroupContextTypeQuit:
return @"OWSSignalServiceProtosGroupContextTypeQuit"; return @"OWSSignalServiceProtosGroupContextTypeQuit";
case OWSSignalServiceProtosGroupContextTypeRequestInfo:
return @"OWSSignalServiceProtosGroupContextTypeRequestInfo";
default: default:
return nil; return nil;
} }

@ -29,11 +29,11 @@ extern NSString *const OWSMimeTypeUnknownForTests;
+ (BOOL)isVideo:(NSString *)contentType; + (BOOL)isVideo:(NSString *)contentType;
+ (BOOL)isAudio:(NSString *)contentType; + (BOOL)isAudio:(NSString *)contentType;
+ (NSString *)filePathForAttachment:(NSString *)uniqueId ofMIMEType:(NSString *)contentType inFolder:(NSString *)folder; // filename is optional and should not be trusted.
+ (NSString *)filePathForImage:(NSString *)uniqueId ofMIMEType:(NSString *)contentType inFolder:(NSString *)folder; + (NSString *)filePathForAttachment:(NSString *)uniqueId
+ (NSString *)filePathForVideo:(NSString *)uniqueId ofMIMEType:(NSString *)contentType inFolder:(NSString *)folder; ofMIMEType:(NSString *)contentType
+ (NSString *)filePathForAudio:(NSString *)uniqueId ofMIMEType:(NSString *)contentType inFolder:(NSString *)folder; filename:(nullable NSString *)filename
+ (NSString *)filePathForAnimated:(NSString *)uniqueId ofMIMEType:(NSString *)contentType inFolder:(NSString *)folder; inFolder:(NSString *)folder;
+ (NSURL *)simLinkCorrectExtensionOfFile:(NSURL *)mediaURL ofMIMEType:(NSString *)contentType; + (NSURL *)simLinkCorrectExtensionOfFile:(NSURL *)mediaURL ofMIMEType:(NSString *)contentType;

@ -261,7 +261,70 @@ NSString *const OWSMimeTypeUnknownForTests = @"unknown/mimetype";
+ (NSString *)filePathForAttachment:(NSString *)uniqueId + (NSString *)filePathForAttachment:(NSString *)uniqueId
ofMIMEType:(NSString *)contentType ofMIMEType:(NSString *)contentType
inFolder:(NSString *)folder { filename:(nullable NSString *)filename
inFolder:(NSString *)folder
{
NSString *kDefaultFileExtension = @"bin";
if (filename.length > 0) {
NSString *normalizedFilename =
[filename stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// Ensure that the filename is a valid filesystem name,
// replacing invalid characters with an underscore.
for (NSCharacterSet *invalidCharacterSet in @[
[NSCharacterSet whitespaceAndNewlineCharacterSet],
[NSCharacterSet illegalCharacterSet],
[NSCharacterSet controlCharacterSet],
[NSCharacterSet characterSetWithCharactersInString:@"<>|\\:()&;?*/~"],
]) {
normalizedFilename = [[normalizedFilename componentsSeparatedByCharactersInSet:invalidCharacterSet]
componentsJoinedByString:@"_"];
}
// Remove leading periods to prevent hidden files,
// "." and ".." special file names.
while ([normalizedFilename hasPrefix:@"."]) {
normalizedFilename = [normalizedFilename substringFromIndex:1];
}
NSString *fileExtension = [[normalizedFilename pathExtension]
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *filenameWithoutExtension = [[[normalizedFilename lastPathComponent] stringByDeletingPathExtension]
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// If the filename has not file extension, deduce one
// from the MIME type.
if (fileExtension.length < 1) {
fileExtension = [self fileExtensionForMIMEType:contentType];
if (fileExtension.length < 1) {
fileExtension = kDefaultFileExtension;
}
}
fileExtension = [fileExtension lowercaseString];
if (filenameWithoutExtension.length > 0) {
// Store the file in a subdirectory whose name is the uniqueId of this attachment,
// to avoid collisions between multiple attachments with the same name.
NSString *attachmentFolderPath = [folder stringByAppendingPathComponent:uniqueId];
NSError *error = nil;
BOOL attachmentFolderPathExists = [[NSFileManager defaultManager] fileExistsAtPath:attachmentFolderPath];
if (!attachmentFolderPathExists) {
[[NSFileManager defaultManager] createDirectoryAtPath:attachmentFolderPath
withIntermediateDirectories:YES
attributes:nil
error:&error];
if (error) {
DDLogError(@"Failed to create attachment directory: %@", error);
OWSAssert(0);
return nil;
}
}
return [attachmentFolderPath
stringByAppendingPathComponent:[NSString
stringWithFormat:@"%@.%@", filenameWithoutExtension, fileExtension]];
}
}
if ([self isVideo:contentType]) { if ([self isVideo:contentType]) {
return [MIMETypeUtil filePathForVideo:uniqueId ofMIMEType:contentType inFolder:folder]; return [MIMETypeUtil filePathForVideo:uniqueId ofMIMEType:contentType inFolder:folder];
} else if ([self isAudio:contentType]) { } else if ([self isAudio:contentType]) {
@ -291,7 +354,7 @@ NSString *const OWSMimeTypeUnknownForTests = @"unknown/mimetype";
DDLogError(@"Got asked for path of file %@ which is unsupported", contentType); DDLogError(@"Got asked for path of file %@ which is unsupported", contentType);
// Use a fallback file extension. // Use a fallback file extension.
return [self filePathForData:uniqueId withFileExtension:@"bin" inFolder:folder]; return [self filePathForData:uniqueId withFileExtension:kDefaultFileExtension inFolder:folder];
} }
+ (NSURL *)simLinkCorrectExtensionOfFile:(NSURL *)mediaURL ofMIMEType:(NSString *)contentType { + (NSURL *)simLinkCorrectExtensionOfFile:(NSURL *)mediaURL ofMIMEType:(NSString *)contentType {

Loading…
Cancel
Save