在版本大于2.2.1时打开SQLCipher 3加密的数据库,会出现DatabaseException 'out of memory'
我在使用 sqflite_sqlcipher 打开一个加密数据库时,在高于 2.2.1 的版本上遇到了崩溃。相同的代码在 2.2.1 上工作正常,但在较新的版本上却始终失败。
代码片段:
Future<Database> _open(String databasePath, String key) async {
try {
if (key.isEmpty) {
return await openDatabase(databasePath, version: 1);
} else {
return await openDatabase(databasePath, password: key, version: 1);
}
} catch (e) {
print(
"Error opening database normally: $e. Retrying with cipher compatibility...");
return await openDatabase(
databasePath,
password: key,
version: 1,
onConfigure: (db) async {
await db.execute('PRAGMA cipher_compatibility = 3;');
},
);
}
}
错误日志:
flutter: 正常打开数据库时出错:DatabaseException(open_failed ..../Documents/9781316644607.db)。正在尝试使用密码兼容性重试……
flutter: 错误DatabaseException(Error Domain=FMDatabase Code=7 "out of memory" UserInfo={NSLocalizedDescription=out of memory}) sql 'BEGIN EXCLUSIVE' args [] during open, closing…
[ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: DatabaseException(Error Domain=FMDatabase Code=7 "out of memory" UserInfo={NSLocalizedDescription=out of memory}) sql 'BEGIN EXCLUSIVE' args []
0 SqfliteSqlCipherDatabaseFactoryImpl.wrapDatabaseException (package:sqflite_sqlcipher/src/factory_sql_cipher_impl.dart:44:9)
#1 SqfliteDatabaseMixin.txnSynchronized (package:sqflite_common/src/database_mixin.dart:554:16)
#2 SqfliteDatabaseMixinExt.txnBeginTransaction (package:sqflite_common/src/database_mixin.dart:411:20)
#3 SqfliteDatabaseMixin.beginTransaction (package:sqflite_common/src/database_mixin.dart:863:5)
#4 SqfliteDatabaseMixinExt._txnTransaction (package:sqflite_common/src/database_mixin.dart:384:13)
#5 BasicLock.synchronized (package:synchronized/src/basic_lock.dart:38:16)
观察结果
在sqflite_sqlcipher 2.2.1上工作正常
在所有高于2.2.1的版本上失败
数据库使用SQLCipher 3进行加密
解决方案
内存不足的问题是由 SQLCipher 版本不匹配引起的。你的数据库是由 SQLCipher3 加密的,在使用新版本尝试打开数据库时,它默认会使用4.x插件,如下链接所述,并抛出异常。
解决方案要么使用较旧版本的应用/数据库,要么将数据库迁移以支持较新的版本。