Merge branch 'charlesmchen/unknownObjectVsNPE'

This commit is contained in:
Matthew Chen 2018-07-23 17:13:52 -04:00 committed by Michael Kirk
parent fd9125ce1a
commit 48fb652d83
2 changed files with 56 additions and 23 deletions

View File

@ -97,12 +97,24 @@ NS_ASSUME_NONNULL_BEGIN
NSMutableArray<NSString *> *interactionIds = [NSMutableArray new];
YapDatabaseViewTransaction *interactionsByThread = [transaction ext:TSMessageDatabaseViewExtensionName];
OWSAssert(interactionsByThread);
[interactionsByThread
enumerateKeysInGroup:self.uniqueId
usingBlock:^(
NSString *_Nonnull collection, NSString *_Nonnull key, NSUInteger index, BOOL *_Nonnull stop) {
[interactionIds addObject:key];
}];
__block BOOL didDetectCorruption = NO;
[interactionsByThread enumerateKeysInGroup:self.uniqueId
usingBlock:^(NSString *collection, NSString *key, NSUInteger index, BOOL *stop) {
if (![key isKindOfClass:[NSString class]] || key.length < 1) {
OWSProdLogAndFail(@"%@ invalid key in thread interactions: %@, %@.",
self.logTag,
key,
[key class]);
didDetectCorruption = YES;
return;
}
[interactionIds addObject:key];
}];
if (didDetectCorruption) {
DDLogWarn(@"%@ incrementing version of: %@", self.logTag, TSMessageDatabaseViewExtensionName);
[OWSPrimaryStorage incrementVersionOfDatabaseExtension:TSMessageDatabaseViewExtensionName];
}
for (NSString *interactionId in interactionIds) {
// We need to fetch each interaction, since [TSInteraction removeWithTransaction:] does important work.
@ -157,13 +169,8 @@ NS_ASSUME_NONNULL_BEGIN
usingBlock:(void (^)(TSInteraction *interaction,
YapDatabaseReadTransaction *transaction))block
{
void (^interactionBlock)(NSString *, NSString *, id, id, NSUInteger, BOOL *) = ^void(NSString *_Nonnull collection,
NSString *_Nonnull key,
id _Nonnull object,
id _Nonnull metadata,
NSUInteger index,
BOOL *_Nonnull stop) {
void (^interactionBlock)(NSString *, NSString *, id, id, NSUInteger, BOOL *) = ^void(
NSString *collection, NSString *key, id _Nonnull object, id _Nonnull metadata, NSUInteger index, BOOL *stop) {
TSInteraction *interaction = object;
block(interaction, transaction);
};
@ -194,7 +201,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSArray<TSInteraction *> *)allInteractions
{
NSMutableArray<TSInteraction *> *interactions = [NSMutableArray new];
[self enumerateInteractionsUsingBlock:^(TSInteraction *_Nonnull interaction) {
[self enumerateInteractionsUsingBlock:^(TSInteraction *interaction) {
[interactions addObject:interaction];
}];
@ -219,7 +226,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSUInteger)numberOfInteractions
{
__block NSUInteger count;
[[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
[[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *transaction) {
YapDatabaseViewTransaction *interactionsByThread = [transaction ext:TSMessageDatabaseViewExtensionName];
count = [interactionsByThread numberOfItemsInGroup:self.uniqueId];
}];

View File

@ -192,7 +192,7 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
#pragma mark -
@interface OWSUnknownDBObject : NSObject <NSCoding>
@interface OWSUnknownDBObject : TSYapDatabaseObject <NSCoding>
@end
@ -205,17 +205,42 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
*/
@implementation OWSUnknownDBObject
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
- (void)encodeWithCoder:(NSCoder *)aCoder
{
// We return self instead of, e.g. nil, to avoid a crash when YapDB enumerates
// all old objects when building a DB extension.
OWSProdLogAndFail(@"%@ Tried to save object from unknown collection", self.logTag);
return [super encodeWithCoder:aCoder];
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSRaiseException(
@"OWSStorageExceptionName_SaveToUnknownCollection", @"Tried to save object from unknown collection");
OWSProdLogAndFail(@"%@ Tried to save unknown object", self.logTag);
// No-op.
}
- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSProdLogAndFail(@"%@ Tried to touch unknown object", self.logTag);
// No-op.
}
- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSProdLogAndFail(@"%@ Tried to remove unknown object", self.logTag);
// No-op.
}
@end
@ -457,7 +482,8 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
return ^id(NSString __unused *collection, NSString __unused *key, NSData *data) {
if (!data || data.length <= 0) {
return nil;
OWSProdLogAndFail(@"%@ can't deserialize null object: %@", self.logTag, collection);
return [OWSUnknownDBObject new];
}
@try {