|
|
@ -35,8 +35,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
return [Randomness generateRandomBytes:30];
|
|
|
|
return [Randomness generateRandomBytes:30];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// * Open a YapDatabase.
|
|
|
|
|
|
|
|
// * Do some work with a block.
|
|
|
|
|
|
|
|
// * Close the database.
|
|
|
|
|
|
|
|
// * Verify that the database is closed.
|
|
|
|
- (void)openYapDatabase:(NSString *)databaseFilePath
|
|
|
|
- (void)openYapDatabase:(NSString *)databaseFilePath
|
|
|
|
databasePassword:(NSData *)databasePassword
|
|
|
|
databasePassword:(NSData *)databasePassword
|
|
|
|
|
|
|
|
databaseSalt:(NSData *_Nullable)databaseSalt
|
|
|
|
databaseBlock:(void (^_Nonnull)(YapDatabase *))databaseBlock
|
|
|
|
databaseBlock:(void (^_Nonnull)(YapDatabase *))databaseBlock
|
|
|
|
{
|
|
|
|
{
|
|
|
|
OWSAssert(databaseFilePath.length > 0);
|
|
|
|
OWSAssert(databaseFilePath.length > 0);
|
|
|
@ -57,6 +62,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
};
|
|
|
|
};
|
|
|
|
options.enableMultiProcessSupport = YES;
|
|
|
|
options.enableMultiProcessSupport = YES;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (databaseSalt) {
|
|
|
|
|
|
|
|
DDLogInfo(@"%@ Using salt & unencrypted header.", self.logTag);
|
|
|
|
|
|
|
|
options.cipherSaltBlock = ^{
|
|
|
|
|
|
|
|
return databaseSalt;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
options.cipherUnencryptedHeaderLength = kSqliteHeaderLength;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
OWSAssert(options.cipherDefaultkdfIterNumber == 0);
|
|
|
|
OWSAssert(options.cipherDefaultkdfIterNumber == 0);
|
|
|
|
OWSAssert(options.kdfIterNumber == 0);
|
|
|
|
OWSAssert(options.kdfIterNumber == 0);
|
|
|
|
OWSAssert(options.cipherPageSize == 0);
|
|
|
|
OWSAssert(options.cipherPageSize == 0);
|
|
|
@ -112,16 +125,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
OWSAssert(!strongDatabase);
|
|
|
|
OWSAssert(!strongDatabase);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (nullable NSString *)createUnconvertedDatabase:(NSData *)databasePassword
|
|
|
|
- (void)createTestDatabase:(NSString *)databaseFilePath databasePassword:(NSData *)databasePassword
|
|
|
|
{
|
|
|
|
{
|
|
|
|
NSString *temporaryDirectory = NSTemporaryDirectory();
|
|
|
|
OWSAssert(databaseFilePath.length > 0);
|
|
|
|
NSString *filename = [NSUUID UUID].UUIDString;
|
|
|
|
OWSAssert(databasePassword.length > 0);
|
|
|
|
NSString *databaseFilePath = [temporaryDirectory stringByAppendingPathComponent:filename];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DDLogInfo(@"%@ databaseFilePath: %@", self.logTag, databaseFilePath);
|
|
|
|
OWSAssert(![[NSFileManager defaultManager] fileExistsAtPath:databaseFilePath]);
|
|
|
|
|
|
|
|
|
|
|
|
[self openYapDatabase:databaseFilePath
|
|
|
|
[self openYapDatabase:databaseFilePath
|
|
|
|
databasePassword:databasePassword
|
|
|
|
databasePassword:databasePassword
|
|
|
|
|
|
|
|
databaseSalt:nil
|
|
|
|
databaseBlock:^(YapDatabase *database) {
|
|
|
|
databaseBlock:^(YapDatabase *database) {
|
|
|
|
YapDatabaseConnection *dbConnection = database.newConnection;
|
|
|
|
YapDatabaseConnection *dbConnection = database.newConnection;
|
|
|
|
[dbConnection setObject:@(YES) forKey:@"test_key_name" inCollection:@"test_collection_name"];
|
|
|
|
[dbConnection setObject:@(YES) forKey:@"test_key_name" inCollection:@"test_collection_name"];
|
|
|
@ -130,21 +143,49 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
|
|
|
|
|
|
|
OWSAssert([[NSFileManager defaultManager] fileExistsAtPath:databaseFilePath]);
|
|
|
|
OWSAssert([[NSFileManager defaultManager] fileExistsAtPath:databaseFilePath]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NSError *_Nullable error = nil;
|
|
|
|
|
|
|
|
NSDictionary *fileAttributes =
|
|
|
|
|
|
|
|
[[NSFileManager defaultManager] attributesOfItemAtPath:databaseFilePath error:&error];
|
|
|
|
|
|
|
|
OWSAssert(fileAttributes && !error);
|
|
|
|
|
|
|
|
DDLogVerbose(@"%@ test database file size: %@", self.logTag, fileAttributes[NSFileSize]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (BOOL)verifyTestDatabase:(NSString *)databaseFilePath
|
|
|
|
|
|
|
|
databasePassword:(NSData *)databasePassword
|
|
|
|
|
|
|
|
databaseSalt:(NSData *_Nullable)databaseSalt
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
OWSAssert(databaseFilePath.length > 0);
|
|
|
|
|
|
|
|
OWSAssert(databasePassword.length > 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OWSAssert([[NSFileManager defaultManager] fileExistsAtPath:databaseFilePath]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__block BOOL isValid = NO;
|
|
|
|
[self openYapDatabase:databaseFilePath
|
|
|
|
[self openYapDatabase:databaseFilePath
|
|
|
|
databasePassword:databasePassword
|
|
|
|
databasePassword:databasePassword
|
|
|
|
|
|
|
|
databaseSalt:databaseSalt
|
|
|
|
databaseBlock:^(YapDatabase *database) {
|
|
|
|
databaseBlock:^(YapDatabase *database) {
|
|
|
|
YapDatabaseConnection *dbConnection = database.newConnection;
|
|
|
|
YapDatabaseConnection *dbConnection = database.newConnection;
|
|
|
|
id _Nullable value = [dbConnection objectForKey:@"test_key_name" inCollection:@"test_collection_name"];
|
|
|
|
id _Nullable value = [dbConnection objectForKey:@"test_key_name" inCollection:@"test_collection_name"];
|
|
|
|
OWSAssert([@(YES) isEqual:value]);
|
|
|
|
isValid = [@(YES) isEqual:value];
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
OWSAssert([[NSFileManager defaultManager] fileExistsAtPath:databaseFilePath]);
|
|
|
|
OWSAssert([[NSFileManager defaultManager] fileExistsAtPath:databaseFilePath]);
|
|
|
|
|
|
|
|
|
|
|
|
NSError *_Nullable error = nil;
|
|
|
|
return isValid;
|
|
|
|
NSDictionary *fileAttributes =
|
|
|
|
}
|
|
|
|
[[NSFileManager defaultManager] attributesOfItemAtPath:databaseFilePath error:&error];
|
|
|
|
|
|
|
|
OWSAssert(fileAttributes && !error);
|
|
|
|
- (nullable NSString *)createUnconvertedDatabase:(NSData *)databasePassword
|
|
|
|
DDLogVerbose(@"%@ test database file size: %@", self.logTag, fileAttributes[NSFileSize]);
|
|
|
|
{
|
|
|
|
|
|
|
|
NSString *temporaryDirectory = NSTemporaryDirectory();
|
|
|
|
|
|
|
|
NSString *filename = [[NSUUID UUID].UUIDString stringByAppendingString:@".sqlite"];
|
|
|
|
|
|
|
|
NSString *databaseFilePath = [temporaryDirectory stringByAppendingPathComponent:filename];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DDLogInfo(@"%@ databaseFilePath: %@", self.logTag, databaseFilePath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[self createTestDatabase:databaseFilePath databasePassword:databasePassword];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOL isValid = [self verifyTestDatabase:databaseFilePath databasePassword:databasePassword databaseSalt:nil];
|
|
|
|
|
|
|
|
OWSAssert(isValid);
|
|
|
|
|
|
|
|
|
|
|
|
return databaseFilePath;
|
|
|
|
return databaseFilePath;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -166,13 +207,26 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
NSData *databasePassword = [self randomDatabasePassword];
|
|
|
|
NSData *databasePassword = [self randomDatabasePassword];
|
|
|
|
NSString *_Nullable databaseFilePath = [self createUnconvertedDatabase:databasePassword];
|
|
|
|
NSString *_Nullable databaseFilePath = [self createUnconvertedDatabase:databasePassword];
|
|
|
|
XCTAssertTrue([OWSDatabaseConverter doesDatabaseNeedToBeConverted:databaseFilePath]);
|
|
|
|
XCTAssertTrue([OWSDatabaseConverter doesDatabaseNeedToBeConverted:databaseFilePath]);
|
|
|
|
NSError *_Nullable error =
|
|
|
|
|
|
|
|
[OWSDatabaseConverter convertDatabaseIfNecessary:databaseFilePath databasePassword:databasePassword];
|
|
|
|
__block NSData *_Nullable databaseSalt = nil;
|
|
|
|
|
|
|
|
OWSDatabaseSaltBlock saltBlock = ^(NSData *saltData) {
|
|
|
|
|
|
|
|
OWSAssert(!databaseSalt);
|
|
|
|
|
|
|
|
OWSAssert(saltData);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
databaseSalt = saltData;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
NSError *_Nullable error = [OWSDatabaseConverter convertDatabaseIfNecessary:databaseFilePath
|
|
|
|
|
|
|
|
databasePassword:databasePassword
|
|
|
|
|
|
|
|
saltBlock:saltBlock];
|
|
|
|
if (error) {
|
|
|
|
if (error) {
|
|
|
|
DDLogError(@"%s error: %@", __PRETTY_FUNCTION__, error);
|
|
|
|
DDLogError(@"%s error: %@", __PRETTY_FUNCTION__, error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
XCTAssertNil(error);
|
|
|
|
XCTAssertNil(error);
|
|
|
|
XCTAssertFalse([OWSDatabaseConverter doesDatabaseNeedToBeConverted:databaseFilePath]);
|
|
|
|
XCTAssertFalse([OWSDatabaseConverter doesDatabaseNeedToBeConverted:databaseFilePath]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOL isValid =
|
|
|
|
|
|
|
|
[self verifyTestDatabase:databaseFilePath databasePassword:databasePassword databaseSalt:databaseSalt];
|
|
|
|
|
|
|
|
XCTAssertTrue(isValid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
@end
|
|
|
|