Refine sync messages.

This commit is contained in:
Matthew Chen 2018-02-02 10:56:16 -05:00
parent 59ff1561f5
commit 799949e546
9 changed files with 80 additions and 54 deletions

View File

@ -22,7 +22,6 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)getOrCreateThreadWithGroupId:(NSData *)groupId
transaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (nullable instancetype)threadWithGroupId:(NSData *)groupId;
+ (nullable instancetype)threadWithGroupId:(NSData *)groupId transaction:(YapDatabaseReadTransaction *)transaction;
+ (NSString *)threadIdFromGroupId:(NSData *)groupId;

View File

@ -58,17 +58,6 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (nullable instancetype)threadWithGroupId:(NSData *)groupId;
{
OWSAssert(groupId.length > 0);
__block TSGroupThread *thread;
[[self dbReadWriteConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
thread = [self threadWithGroupId:groupId transaction:transaction];
}];
return thread;
}
+ (nullable instancetype)threadWithGroupId:(NSData *)groupId transaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssert(groupId.length > 0);

View File

@ -1,14 +1,17 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSChunkedOutputStream.h"
NS_ASSUME_NONNULL_BEGIN
@class TSGroupModel;
@class YapDatabaseReadTransaction;
@interface OWSGroupsOutputStream : OWSChunkedOutputStream
- (void)writeGroup:(TSGroupModel *)group;
- (void)writeGroup:(TSGroupModel *)group transaction:(YapDatabaseReadTransaction *)transaction;
@end

View File

@ -14,8 +14,11 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSGroupsOutputStream
- (void)writeGroup:(TSGroupModel *)group
- (void)writeGroup:(TSGroupModel *)group transaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssert(group);
OWSAssert(transaction);
OWSSignalServiceProtosGroupDetailsBuilder *groupBuilder = [OWSSignalServiceProtosGroupDetailsBuilder new];
[groupBuilder setId:group.groupId];
[groupBuilder setName:group.groupName];
@ -37,10 +40,10 @@ NS_ASSUME_NONNULL_BEGIN
[self.delegateStream writeRawVarint32:groupDataLength];
[self.delegateStream writeRawData:groupData];
TSGroupThread *_Nullable groupThread = [TSGroupThread threadWithGroupId:group.groupId];
TSGroupThread *_Nullable groupThread = [TSGroupThread threadWithGroupId:group.groupId transaction:transaction];
if (groupThread) {
OWSDisappearingMessagesConfiguration *_Nullable disappearingMessagesConfiguration =
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:groupThread.uniqueId];
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:groupThread.uniqueId transaction:transaction];
if (disappearingMessagesConfiguration && disappearingMessagesConfiguration.isEnabled) {
[groupBuilder setExpireTimer:disappearingMessagesConfiguration.durationSeconds];

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "DataSource.h"
@ -53,6 +53,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)deleteAttachments;
+ (NSString *)attachmentsFolder;
- (BOOL)shouldHaveImageSize;
- (CGSize)imageSize;
- (CGFloat)audioDurationSeconds;

View File

@ -19,9 +19,11 @@ NS_ASSUME_NONNULL_BEGIN
// changes in the file path generation logic don't break existing attachments.
@property (nullable, nonatomic) NSString *localRelativeFilePath;
// These properties should only be accessed on the main thread.
// These properties should only be accessed while synchronized on self.
@property (nullable, nonatomic) NSNumber *cachedImageWidth;
@property (nullable, nonatomic) NSNumber *cachedImageHeight;
// This property should only be accessed on the main thread.
@property (nullable, nonatomic) NSNumber *cachedAudioDurationSeconds;
@end
@ -105,8 +107,11 @@ NS_ASSUME_NONNULL_BEGIN
if (attachmentSchemaVersion < 4) {
// Legacy image sizes don't correctly reflect image orientation.
self.cachedImageWidth = nil;
self.cachedImageHeight = nil;
@synchronized(self)
{
self.cachedImageWidth = nil;
self.cachedImageHeight = nil;
}
}
}
@ -390,35 +395,46 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (BOOL)shouldHaveImageSize
{
return ([self isVideo] || [self isImage] || [self isAnimated]);
}
- (CGSize)imageSize
{
OWSAssertIsOnMainThread();
OWSAssert(self.shouldHaveImageSize);
if (self.cachedImageWidth && self.cachedImageHeight) {
return CGSizeMake(self.cachedImageWidth.floatValue, self.cachedImageHeight.floatValue);
}
CGSize imageSize = [self calculateImageSize];
self.cachedImageWidth = @(imageSize.width);
self.cachedImageHeight = @(imageSize.height);
[self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
NSString *collection = [[self class] collection];
TSAttachmentStream *latestInstance = [transaction objectForKey:self.uniqueId inCollection:collection];
if (latestInstance) {
latestInstance.cachedImageWidth = @(imageSize.width);
latestInstance.cachedImageHeight = @(imageSize.height);
[latestInstance saveWithTransaction:transaction];
} else {
// This message has not yet been saved or has been deleted; do nothing.
// This isn't an error per se, but these race conditions should be
// _very_ rare.
OWSFail(@"%@ Attachment not yet saved.", self.logTag);
@synchronized(self)
{
if (self.cachedImageWidth && self.cachedImageHeight) {
return CGSizeMake(self.cachedImageWidth.floatValue, self.cachedImageHeight.floatValue);
}
}];
return imageSize;
CGSize imageSize = [self calculateImageSize];
if (imageSize.width <= 0 || imageSize.height <= 0) {
return CGSizeZero;
}
self.cachedImageWidth = @(imageSize.width);
self.cachedImageHeight = @(imageSize.height);
[self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
NSString *collection = [[self class] collection];
TSAttachmentStream *latestInstance = [transaction objectForKey:self.uniqueId inCollection:collection];
if (latestInstance) {
latestInstance.cachedImageWidth = @(imageSize.width);
latestInstance.cachedImageHeight = @(imageSize.height);
[latestInstance saveWithTransaction:transaction];
} else {
// This message has not yet been saved or has been deleted; do nothing.
// This isn't an error per se, but these race conditions should be
// _very_ rare.
OWSFail(@"%@ Attachment not yet saved.", self.logTag);
}
}];
return imageSize;
}
}
- (CGFloat)calculateAudioDurationSeconds

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSSyncGroupsMessage.h"
@ -57,7 +57,7 @@ NS_ASSUME_NONNULL_BEGIN
return;
}
TSGroupModel *group = ((TSGroupThread *)obj).groupModel;
[groupsOutputStream writeGroup:group];
[groupsOutputStream writeGroup:group transaction:transaction];
}];
[groupsOutputStream flush];

View File

@ -535,13 +535,15 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
[builder setDigest:attachmentStream.digest];
[builder setFlags:(self.isVoiceMessage ? OWSSignalServiceProtosAttachmentPointerFlagsVoiceMessage : 0)];
CGSize imageSize = [attachmentStream imageSize];
if (imageSize.width < NSIntegerMax && imageSize.height < NSIntegerMax) {
NSInteger imageWidth = (NSInteger)round(imageSize.width);
NSInteger imageHeight = (NSInteger)round(imageSize.height);
if (imageWidth > 0 && imageHeight > 0) {
[builder setWidth:(UInt32)imageWidth];
[builder setHeight:(UInt32)imageHeight];
if ([attachmentStream shouldHaveImageSize]) {
CGSize imageSize = [attachmentStream imageSize];
if (imageSize.width < NSIntegerMax && imageSize.height < NSIntegerMax) {
NSInteger imageWidth = (NSInteger)round(imageSize.width);
NSInteger imageHeight = (NSInteger)round(imageSize.height);
if (imageWidth > 0 && imageHeight > 0) {
[builder setWidth:(UInt32)imageWidth];
[builder setHeight:(UInt32)imageHeight];
}
}
}

View File

@ -312,6 +312,19 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(dataMessage);
OWSAssert(transaction);
if (dataMessage.hasTimestamp) {
if (dataMessage.timestamp <= 0) {
DDLogError(@"%@ Ignoring message with invalid data message timestamp: %@", self.logTag, envelope.source);
return;
}
// This prevents replay attacks by the service.
if (dataMessage.timestamp != envelope.timestamp) {
DDLogError(
@"%@ Ignoring message with non-matching data message timestamp: %@", self.logTag, envelope.source);
return;
}
}
if ([dataMessage hasProfileKey]) {
NSData *profileKey = [dataMessage profileKey];
NSString *recipientId = envelope.source;