Hello,
I am upgrading sqlChiper library in my project to support 16kb devicces,
from: implementation 'net.zetetic:android-database-sqlcipher:4.2.0@aar'
to: implementation 'net.zetetic:sqlcipher-android:4.6.1@aar'
during this update some I have noticed that somefunctions were modified,
currently I am getting a crash, when using the SQLiteDatabaseHook
I have noticed that the SQLiteDatabaseHook preKey and postKey were changed and now are receiving connection: SQLiteConnection? in the functions,
previously it was SQLiteDatabase and I used database.rawExecSQL("PRAGMA cipher_migrate") which worked, now the equivalent connection?.executeRaw("PRAGMA cipher_migrate", null, null) is causing a crash, but was sufficient up until 4.2.0.
I have also read some previous comments and saw that there are some more queries that might resolve the issue, I have also tried
But this is throwing the following: android.database.sqlite.SQLiteException: file is not a database (code 26): , while compiling: ATTACH DATABASE 'history_log_new.db' as sqlcipher4 KEY ‘…..’
You should not need to set cipher_compatibility or cipher_page_size unless those values were previously used to configure access to the database in question. In terms of migrating your database, if you were previously able to access your database without invoking cipher_migrate, you would not need to invoke that either as it’s purpose is to migrate SQLCipher database files from previous major versions of SQLCipher (e.g., a SQLCipher 3 database file migrating to SQLCipher 4).
Should you need to perform a cipher_migrate command within the postKey hook, you can use the method executeForLong to check to the result of your migration. An example is available within our test suite here.
Hi,
Thanks for the comment!
This solution works on a normal emulator, but when I try it on a SDK 35 16kb version emulator it crashes with the following as soon as I try to write to the db:
Failed to open database ‘/data/user/0/com.app/databases/user’. android.database.sqlite.SQLiteException: SQL logic error (code 1): , while compiling: SELECT COUNT(*) FROM sqlite_schema;
any advice?
I just ran through a small test using SQLCipher for Android 4.6.1 Community edition on both the standard API 35 and API 35 (16kb page size) emulators, both operated properly.
Can you create a small, standalone sample application and publish it on GitHub that reproduces the scenario you are seeing in isolation? We’d be happy to look into this further. Thanks!
Hi @developernotes
Thanks a lot for trying to resolve this with me, can I see the project you tried running with the API 35 (16kb page size edition) for compheresent (is there any git repo with it, or can I ask you to push it somewhere so I can have a look at it please?
even if I will create some side project that would work on a 16kb emulator this would not help me since my goal is to make the primary project work, it works great on a normal emulator, but I was unsecseful in resolving the crash on the 16kb version ones, do you maybe have some kind of suggestions or ideas why is this happening? any lead would be very appriciated,
thanks!
I used the sample source we make available within our online integration instructions here. If you are able to create a reproducible scenario we would be happy to investigate further.
The benefit in creating an isolated reproduction of the issue is to verify the issue exists outside of your primary project work. If you’re unable to reproduce the issue in isolation, you might compare the differences in your API usage from the demo (that works) in relation to your primary project (which doesn’t) for any differences.
Hi @developernotes,I hope you had a good weekend,
after debugging the latest code I came to realize it is crashing in the openOrCreateDatabase function,
this is my hook class:
class MyDatabaseHook() : SQLiteDatabaseHook {
override fun preKey(connection: SQLiteConnection?) {}
override fun postKey(connection: SQLiteConnection?) {
connection?.executeForLong("PRAGMA cipher_migrate", null, null)
}
}
I use it like this:
public SQLiteDatabase open() throws Exception {
MyDatabaseHook hook = new MyDatabaseHook();
return SQLiteDatabase.openOrCreateDatabase(databaseFile.getAbsolutePath(), getKey(), null, null, hook);
}
this function is throwing Method threw 'android.database.sqlite.SQLiteException' exception. with detailMessage: SQL logic error (code 1): , while compiling: SELECT COUNT(*) FROM sqlite_schema;
I have also debbugged the code of the sqlCHiper and saw that exception is thrown in the class: public final class SQLiteConnection
in the function:
public long executeForLong(String sql, Object[] bindArgs,
CancellationSignal cancellationSignal)
the exception caught in the debug is shown in the attached screen shot, android.database.sqlite.SQLiteDoneException
Have you tried to perform a PRAGMA cipher_migrate on the database in question using a SQLCipher 4.x command line tool? If not, you should try that and see if you’re able to access the database afterwards. If you have, what were your results? Finally, having a small reproduction case of your issue in a public repository would be best to allow us to further investigate.
I’ll try to explain the issue in detail. The migration seems fine, and everything works correctly when I update from an older version using SQLCipher 3.5.9 to the latest version 4.6.1 (on a non 16kb emulator). The problem arises in a specific scenario:
On a 16 KB device, with a clean install (with or without the hook), everything works as expected.
However, when updating from an older version, the app crashes when trying to create the database using the following code:
The crash happens within the SQLCipher code, throwing the following exception: android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5): , while compiling: SELECT COUNT(*) FROM sqlite_schema;
the hook class:
class MyDatabaseHook : SQLiteDatabaseHook {
override fun preKey(connection: SQLiteConnection?) {}
override fun postKey(connection: SQLiteConnection?) {
connection?.executeRaw("PRAGMA cipher_migrate", null, null)
}
}
I have tried many ways in all possible combinations, also with the executeForLong like you suggested,
this issue does not occur on non-16 KB devices or emulators, where the migration works as expected.
if try a clean install without migration from sqlchiper 3, it also works fine, on both 16kb and non 16kb emulators,
Any guidance or suggestions would be greatly appreciated!
Hello @coder123 - 3.5.9 would not run on a 16KB emulator. Thus it is not clear how you would even be testing a migration scenario between an earlier version.
Since we have gone back and forth on this thread 8 or 9 times already, and have thus far been unable to reproduce, it would be best if you would create a small standalone android application that demonstrates the exact problem you are experiencing. Then push it to github and we will download it and attempt to troubleshoot.
I am installing a 3.5.9 version which is currently in the play store, it crashes of course, and then I try to update to the newest version of the 4.6.1, when ever the 16kb devices will be released the some of the users will have the old version pre-installed, therefore I am trying to address an updating issue I am having…
The exception occurs exclusively when upgrading from version 3 to version 4 on a 16KB device. How can I create a standalone app to replicate this behavior? Were there no other reports highlighting this issue?
@coder123 - no we have not had any other reports of issues related 16kb devices or emulators.
If you install your 3.5.9 application on a 16k emulator, run it, experience a crash, then install the 4.6.1version, are you able to reproduce the problem?
The crash happens within the SQLCipher code, throwing the following exception: android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5): , while compiling: SELECT COUNT(*) FROM sqlite_schema;
the hook class:
class MyDatabaseHook : SQLiteDatabaseHook {
override fun preKey(connection: SQLiteConnection?) {}
override fun postKey(connection: SQLiteConnection?) {
connection?.executeRaw("PRAGMA cipher_migrate", null, null)
}
}
@coder123 great, then what I would recommend doing this:
Create a new standalone android application project that establishes a database using 3.5.9 and commit it to git.
Run that on the 16kb emulator
Create a new branch in the git repo, and upgrade the project to 4.6.1, and implement the migration in the same way you do in the same way you are doing in your project
Deploy that to the android 16kb emulator, and see if you are able to reproduce the crash you described
If you are able to reproduce, publish the git repo to github (including both the original and migration branches). We will then download it and troubleshoot it with the minimal reproduction.
If you are not able to reproduce, compare the new implementation to your application to determine what is different.