Merge branch 'charlesmchen/unknownObjectVsNPE'

pull/1/head
Matthew Chen 7 years ago committed by Michael Kirk
parent fd9125ce1a
commit 48fb652d83

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

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

Loading…
Cancel
Save