├── .github └── stale.yml ├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── 1x-user-version.db │ ├── 1x.db │ ├── 2x.db │ ├── corrupt.db │ ├── hello.db │ ├── mutf8.db │ ├── scrolling.db │ ├── sqlcipher-3.0-testkey.db │ └── unencrypted.db │ ├── java │ └── net │ │ └── zetetic │ │ ├── NativeInitializer.java │ │ ├── QueryHelper.java │ │ ├── ScrollingCursorAdapter.java │ │ ├── TestResultAdapter.java │ │ ├── ZeteticApplication.java │ │ ├── ZeteticContentProvider.java │ │ ├── ZeteticContentProvider2.java │ │ ├── activities │ │ ├── TestRunnerSelectionActivity.java │ │ ├── TestScrollingCursorActivity.java │ │ └── TestSuiteBehaviorsActivity.java │ │ └── tests │ │ ├── AES128CipherTest.java │ │ ├── AccessDatabaseTest.java │ │ ├── AttachDatabaseTest.java │ │ ├── AttachExistingDatabaseTest.java │ │ ├── AttachNewDatabaseTest.java │ │ ├── AutoVacuumOverReadTest.java │ │ ├── AverageOpenTimeTest.java │ │ ├── BeginTransactionTest.java │ │ ├── BindBooleanRawQueryTest.java │ │ ├── BindByteArrayRawQueryTest.java │ │ ├── BindDoubleRawQueryTest.java │ │ ├── BindFloatRawQueryTest.java │ │ ├── BindLongRawQueryTest.java │ │ ├── BindStringRawQueryTest.java │ │ ├── CanThrowSQLiteExceptionTest.java │ │ ├── ChangePasswordTest.java │ │ ├── CheckIsDatabaseIntegrityOkTest.java │ │ ├── CheckIsWriteAheadLoggingEnabledTest.java │ │ ├── CipherMigrateTest.java │ │ ├── ClosedDatabaseTest.java │ │ ├── CompileBeginTest.java │ │ ├── CompileStatementSyntaxErrorMessageTest.java │ │ ├── CompiledSQLUpdateTest.java │ │ ├── ComputeKDFTest.java │ │ ├── CopyStringToBufferNullTest.java │ │ ├── CopyStringToBufferTestFloatLargeBuffer.java │ │ ├── CopyStringToBufferTestFloatSmallBuffer.java │ │ ├── CopyStringToBufferTestIntegerLargeBuffer.java │ │ ├── CopyStringToBufferTestIntegerSmallBuffer.java │ │ ├── CopyStringToBufferTestStringLargeBuffer.java │ │ ├── CopyStringToBufferTestStringSmallBuffer.java │ │ ├── CorruptDatabaseTest.java │ │ ├── CreateNonEncryptedDatabaseTest.java │ │ ├── CreateOpenDatabaseWithByteArrayTest.java │ │ ├── CrossProcessCursorQueryTest.java │ │ ├── CursorAccessTest.java │ │ ├── CustomCorruptionHandlerTest.java │ │ ├── DefaultCursorWindowAllocationTest.java │ │ ├── DeleteFunctionTest.java │ │ ├── DeleteTableWithNullWhereArgsTest.java │ │ ├── DisableWriteAheadLoggingTest.java │ │ ├── EnableForeignKeyConstraintsTest.java │ │ ├── EnableForeignKeySupportTest.java │ │ ├── EnableWriteAheadLoggingTest.java │ │ ├── ExecuteInsertConstraintErrorMessageTest.java │ │ ├── ExportToUnencryptedDatabase.java │ │ ├── FIPSTest.java │ │ ├── FTS5Test.java │ │ ├── FixedCursorWindowAllocationTest.java │ │ ├── ForeignKeyConstraintsEnabledWithTransactionTest.java │ │ ├── FullTextSearchTest.java │ │ ├── GetAttachedDatabasesTest.java │ │ ├── GetTypeFromCrossProcessCursorWrapperTest.java │ │ ├── GrowingCursorWindowAllocationTest.java │ │ ├── ICUTest.java │ │ ├── ImportUnencryptedDatabaseTest.java │ │ ├── InsertWithOnConflictTest.java │ │ ├── InterprocessBlobQueryTest.java │ │ ├── InvalidOpenArgumentTest.java │ │ ├── InvalidPasswordTest.java │ │ ├── JavaClientLibraryVersionTest.java │ │ ├── JsonCastTest.java │ │ ├── LargeDatabaseCursorAccessTest.java │ │ ├── LoopingCountQueryTest.java │ │ ├── LoopingInsertTest.java │ │ ├── LoopingQueryTest.java │ │ ├── MUTF8ToUTF8WithNullMigrationTest.java │ │ ├── MigrateDatabaseFrom1xFormatToCurrentFormat.java │ │ ├── MigrationUserVersion.java │ │ ├── MultiThreadReadWriteTest.java │ │ ├── NestedTransactionsTest.java │ │ ├── NullQueryResultTest.java │ │ ├── NullRawQueryTest.java │ │ ├── OpenReadOnlyDatabaseTest.java │ │ ├── OpenSQLCipher3DatabaseTest.java │ │ ├── PragmaCipherVersionTest.java │ │ ├── PreventUpdateWithNullWhereArgsFromThrowingExceptionTest.java │ │ ├── QueryDataSizeTest.java │ │ ├── QueryFloatToStringTest.java │ │ ├── QueryIntegerToStringTest.java │ │ ├── QueryLimitTest.java │ │ ├── QueryNonEncryptedDatabaseTest.java │ │ ├── QueryTenThousandDataTest.java │ │ ├── RTreeTest.java │ │ ├── RawExecSQLExceptionTest.java │ │ ├── RawExecSQLTest.java │ │ ├── RawQueryNoSuchFunctionErrorMessageTest.java │ │ ├── RawQueryNonsenseStatementErrorMessageTest.java │ │ ├── RawQuerySyntaxErrorMessageTest.java │ │ ├── RawQueryTest.java │ │ ├── RawRekeyTest.java │ │ ├── ReadWriteDatabaseToExternalStorageTest.java │ │ ├── ReadWriteUserVersionTest.java │ │ ├── ReadWriteWriteAheadLoggingTest.java │ │ ├── ReadableDatabaseTest.java │ │ ├── ReadableWritableAccessTest.java │ │ ├── ReadableWritableInvalidPasswordTest.java │ │ ├── ResetQueryCacheFinalizesSqlStatementAndReleasesReferenceTest.java │ │ ├── ResultNotifier.java │ │ ├── RowColumnValueBuilder.java │ │ ├── SQLCipherTest.java │ │ ├── SQLiteOpenHelperConfigureTest.java │ │ ├── SQLiteOpenHelperEnableWriteAheadLogAfterGetDatabaseTest.java │ │ ├── SQLiteOpenHelperEnableWriteAheadLogBeforeGetDatabaseTest.java │ │ ├── SQLiteOpenHelperGetNameTest.java │ │ ├── SQLiteOpenHelperOnDowngradeTest.java │ │ ├── SQLiteOpenHelperWithByteArrayKeyTest.java │ │ ├── SimpleQueryTest.java │ │ ├── SoundexTest.java │ │ ├── StatusMemoryUsedTest.java │ │ ├── SummingStepTest.java │ │ ├── TestResult.java │ │ ├── TestSuiteRunner.java │ │ ├── TextAsDoubleTest.java │ │ ├── TextAsIntegerTest.java │ │ ├── TextAsLongTest.java │ │ ├── TimeLargeByteArrayQueryTest.java │ │ ├── TimeQueryExecutionTest.java │ │ ├── TransactionNonExclusiveTest.java │ │ ├── TransactionWithListenerTest.java │ │ ├── UnicodeTest.java │ │ ├── VerifyCipherProviderTest.java │ │ ├── VerifyCipherProviderVersionTest.java │ │ ├── VerifyOnUpgradeIsCalledTest.java │ │ ├── VerifyUTF8EncodingForKeyTest.java │ │ ├── WriteAheadLoggingWithAttachedDatabaseTest.java │ │ ├── WriteAheadLoggingWithInMemoryDatabaseTest.java │ │ ├── WriteAheadLoggingWithTransactionTest.java │ │ └── support │ │ ├── AES128CipherTest.java │ │ ├── AttachDatabaseTest.java │ │ ├── AttachNewDatabaseTest.java │ │ ├── AutoVacuumOverReadTest.java │ │ ├── BeginTransactionTest.java │ │ ├── BindBooleanRawQueryTest.java │ │ ├── BindByteArrayRawQueryTest.java │ │ ├── BindDoubleRawQueryTest.java │ │ ├── BindFloatRawQueryTest.java │ │ ├── BindLongRawQueryTest.java │ │ ├── BindStringRawQueryTest.java │ │ ├── CanThrowSQLiteExceptionTest.java │ │ ├── CheckIsDatabaseIntegrityOkTest.java │ │ ├── CheckIsWriteAheadLoggingEnabledTest.java │ │ ├── CipherMigrateTest.java │ │ ├── ClosedDatabaseTest.java │ │ ├── CompileBeginTest.java │ │ ├── CompileStatementSyntaxErrorMessageTest.java │ │ ├── CompiledSQLUpdateTest.java │ │ ├── ComputeKDFTest.java │ │ ├── CopyStringToBufferNullTest.java │ │ ├── CopyStringToBufferTestFloatLargeBuffer.java │ │ ├── CopyStringToBufferTestFloatSmallBuffer.java │ │ ├── CopyStringToBufferTestIntegerLargeBuffer.java │ │ ├── CopyStringToBufferTestIntegerSmallBuffer.java │ │ ├── CopyStringToBufferTestStringLargeBuffer.java │ │ ├── CopyStringToBufferTestStringSmallBuffer.java │ │ ├── CreateOpenDatabaseWithByteArrayTest.java │ │ ├── CursorAccessTest.java │ │ ├── DecryptedRoomTest.java │ │ ├── DisableWriteAheadLoggingTest.java │ │ ├── EnableForeignKeyConstraintsTest.java │ │ ├── EnableForeignKeySupportTest.java │ │ ├── EnableWriteAheadLoggingTest.java │ │ ├── EncryptBytesTest.java │ │ ├── EncryptedRoomTest.java │ │ ├── ExecuteInsertConstraintErrorMessageTest.java │ │ ├── ExportToUnencryptedDatabase.java │ │ ├── FIPSTest.java │ │ ├── FTS5Test.java │ │ ├── FixedCursorWindowAllocationTest.java │ │ ├── ForeignKeyConstraintsEnabledWithTransactionTest.java │ │ ├── FullTextSearchTest.java │ │ ├── GetAttachedDatabasesTest.java │ │ ├── GetTypeFromCrossProcessCursorWrapperTest.java │ │ ├── GrowingCursorWindowAllocationTest.java │ │ ├── ISupportTest.java │ │ ├── ImportUnencryptedDatabaseTest.java │ │ ├── InsertWithOnConflictTest.java │ │ ├── InvalidPasswordTest.java │ │ ├── JavaClientLibraryVersionTest.java │ │ ├── LargeDatabaseCursorAccessTest.java │ │ ├── LoopingCountQueryTest.java │ │ ├── LoopingInsertTest.java │ │ ├── LoopingQueryTest.java │ │ ├── MigrateDatabaseFrom1xFormatToCurrentFormat.java │ │ ├── MigrationUserVersion.java │ │ ├── NestedTransactionsTest.java │ │ ├── NullQueryResultTest.java │ │ ├── NullRawQueryTest.java │ │ ├── PragmaCipherVersionTest.java │ │ ├── QueryDataSizeTest.java │ │ ├── QueryFloatToStringTest.java │ │ ├── QueryIntegerToStringTest.java │ │ ├── QueryLimitTest.java │ │ ├── QueryTenThousandDataTest.java │ │ ├── RTreeTest.java │ │ ├── RawExecSQLExceptionTest.java │ │ ├── RawExecSQLTest.java │ │ ├── RawQueryNoSuchFunctionErrorMessageTest.java │ │ ├── RawQueryNonsenseStatementErrorMessageTest.java │ │ ├── RawQuerySyntaxErrorMessageTest.java │ │ ├── RawQueryTest.java │ │ ├── RawRekeyTest.java │ │ ├── ReadWriteDatabaseToExternalStorageTest.java │ │ ├── ReadWriteUserVersionTest.java │ │ ├── ReadWriteWriteAheadLoggingTest.java │ │ ├── ReadableDatabaseTest.java │ │ ├── ReadableWritableAccessTest.java │ │ ├── ReadableWritableInvalidPasswordTest.java │ │ ├── RoomTest.java │ │ ├── RoomUpsertTest.java │ │ ├── SQLiteCompiledSqlExceptionTest.java │ │ ├── SQLiteOpenHelperConfigureTest.java │ │ ├── SQLiteOpenHelperEnableWriteAheadLogAfterGetDatabaseTest.java │ │ ├── SQLiteOpenHelperEnableWriteAheadLogBeforeGetDatabaseTest.java │ │ ├── SQLiteOpenHelperGetNameTest.java │ │ ├── SQLiteOpenHelperOnDowngradeTest.java │ │ ├── SQLiteOpenHelperWithByteArrayKeyTest.java │ │ ├── SoundexTest.java │ │ ├── StatusMemoryUsedTest.java │ │ ├── SupportSuiteRunner.java │ │ ├── SupportTest.java │ │ ├── TextAsDoubleTest.java │ │ ├── TextAsIntegerTest.java │ │ ├── TextAsLongTest.java │ │ ├── TimeQueryExecutionTest.java │ │ ├── TransactionNonExclusiveTest.java │ │ ├── TransactionWithListenerTest.java │ │ ├── UnicodeTest.java │ │ ├── VerifyCipherProviderTest.java │ │ ├── VerifyCipherProviderVersionTest.java │ │ ├── VerifyOnUpgradeIsCalledTest.java │ │ ├── VerifyUTF8EncodingForKeyTest.java │ │ ├── WriteAheadLoggingWithAttachedDatabaseTest.java │ │ ├── WriteAheadLoggingWithInMemoryDatabaseTest.java │ │ └── WriteAheadLoggingWithTransactionTest.java │ └── res │ ├── drawable-hdpi │ └── icon.png │ ├── drawable-ldpi │ └── icon.png │ ├── drawable-mdpi │ └── icon.png │ ├── drawable-xhdpi │ └── icon.png │ ├── layout │ ├── cursor_item.xml │ ├── main.xml │ ├── scrolling_cursor_view.xml │ ├── test_result_row.xml │ ├── test_runners.xml │ └── test_stats.xml │ └── values │ └── strings.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── run-testsuite.sh └── settings.gradle /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | # Number of days of inactivity before an issue becomes stale 3 | daysUntilStale: 14 4 | # Number of days of inactivity before a stale issue is closed 5 | daysUntilClose: 14 6 | # Issues with these labels will never be considered stale 7 | exemptLabels: 8 | - bug 9 | - enhancement 10 | - security 11 | # Label to use when marking an issue as stale 12 | staleLabel: stale 13 | # Comment to post when marking an issue as stale. Set to `false` to disable 14 | markComment: > 15 | Hello, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. 16 | You may also label this issue as "bug", "enhancement", or "security" and I will leave it open. 17 | Thank you for your contributions. 18 | # Comment to post when closing a stale issue. Set to `false` to disable 19 | closeComment: > 20 | Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to reopen with up-to-date information. 21 | only: issues 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | **/*.class 3 | **/*.apk 4 | target 5 | *.log 6 | build 7 | .gradle 8 | .idea 9 | local.properties 10 | .idea/** 11 | *.iml 12 | *.aar 13 | *.jar 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008, ZETETIC LLC 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the ZETETIC LLC nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY 16 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Deprecated 2 | 3 | This project exists in support of the `android-database-sqlcipher` project which has been [officially deprecated](https://www.zetetic.net/blog/2023/08/31/sqlcipher-4.5.5-release#sqlcipher-android-455). The long-term replacement is [`sqlcipher-android`](https://github.com/sqlcipher/sqlcipher-android). Instructions for migrating from `android-database-sqlcipher` to `sqlcipher-android`may be found [here](https://www.zetetic.net/sqlcipher/sqlcipher-for-android-migration/). 4 | 5 | 6 | To run: clone this repo and open with a recent version of Android Studio, or [build from the command line](https://developer.android.com/studio/build/building-cmdline). 7 | 8 | It is possible to run on an emulator or device, as documented in the [SQLCipher for Android compatibility section](https://github.com/sqlcipher/android-database-sqlcipher#compatibility). 9 | 10 | More information can be found in [SQLCipher for Android](https://zetetic.net/sqlcipher/sqlcipher-for-android/). 11 | 12 | ### Creating A New Test 13 | 14 | 1. Open this repository within Android Studio 15 | 2. Add a new class within `net.zetetic.tests` package that extends `SQLCipherTest`: 16 | 17 | ```Java 18 | package net.zetetic.tests; 19 | 20 | import net.sqlcipher.database.SQLiteDatabase; 21 | 22 | public class AwesomeTest extends SQLCipherTest { 23 | 24 | @Override 25 | public boolean execute(SQLiteDatabase database) { 26 | try { 27 | // Add your scenario here 28 | return true; 29 | } catch (Exception e) { 30 | return false; 31 | } 32 | } 33 | 34 | @Override 35 | public String getName() { 36 | return "Awesome Test"; 37 | } 38 | } 39 | ``` 40 | 41 | 3. Add `AwesomeTest` to the [`TestSuiteRunner`](https://github.com/sqlcipher/sqlcipher-android-tests/blob/master/src/main/java/net/zetetic/tests/TestSuiteRunner.java): 42 | 43 | ```Java 44 | tests.add(new AwesomeTest()); 45 | ``` 46 | 4. Build and run the application on an Android device or emulator 47 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 33 5 | 6 | defaultConfig { 7 | applicationId "net.zetetic.sqlcipher.test" 8 | minSdkVersion 21 9 | targetSdkVersion 33 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | namespace 'net.zetetic' 20 | } 21 | 22 | dependencies { 23 | // For testing JAR-based distribution: 24 | // implementation files('libs/sqlcipher.jar') 25 | 26 | // For testing local AAR packages: 27 | //implementation (name: 'android-database-sqlcipher-4.5.4-release', ext: 'aar') 28 | 29 | // For testing on remote AAR references: 30 | implementation 'net.zetetic:android-database-sqlcipher:4.5.4@aar' 31 | 32 | implementation "androidx.sqlite:sqlite:2.2.0" 33 | 34 | // For Room tests: 35 | def room_version = "2.5.0" 36 | implementation "androidx.room:room-runtime:$room_version" 37 | annotationProcessor "androidx.room:room-compiler:$room_version" 38 | 39 | // For version comparison 40 | implementation "org.apache.maven:maven-artifact:3.8.7" 41 | } 42 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/nparker/bin/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/assets/1x-user-version.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/assets/1x-user-version.db -------------------------------------------------------------------------------- /app/src/main/assets/1x.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/assets/1x.db -------------------------------------------------------------------------------- /app/src/main/assets/2x.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/assets/2x.db -------------------------------------------------------------------------------- /app/src/main/assets/corrupt.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/assets/corrupt.db -------------------------------------------------------------------------------- /app/src/main/assets/hello.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/assets/hello.db -------------------------------------------------------------------------------- /app/src/main/assets/mutf8.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/assets/mutf8.db -------------------------------------------------------------------------------- /app/src/main/assets/scrolling.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/assets/scrolling.db -------------------------------------------------------------------------------- /app/src/main/assets/sqlcipher-3.0-testkey.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/assets/sqlcipher-3.0-testkey.db -------------------------------------------------------------------------------- /app/src/main/assets/unencrypted.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/assets/unencrypted.db -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/NativeInitializer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic; 2 | import android.util.Log; 3 | 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class NativeInitializer { 7 | 8 | static { 9 | Log.i("NativeInitializer", "Before loadLibs"); 10 | SQLiteDatabase.loadLibs(ZeteticApplication.getInstance()); 11 | Log.i("NativeInitializer", "After loadLibs"); 12 | } 13 | 14 | public static void initialize(){} 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/QueryHelper.java: -------------------------------------------------------------------------------- 1 | package net.zetetic; 2 | 3 | import android.database.Cursor; 4 | import androidx.sqlite.db.SupportSQLiteDatabase; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | 10 | public class QueryHelper { 11 | 12 | public static List getListFromQuery(SupportSQLiteDatabase database, String query){ 13 | Cursor cursor = database.query(query, new String[]{}); 14 | List results = new ArrayList<>(); 15 | if(cursor != null){ 16 | while(cursor.moveToNext()){ 17 | results.add(cursor.getString(0)); 18 | } 19 | cursor.close(); 20 | } 21 | return results; 22 | } 23 | 24 | public static String singleValueFromQuery(SupportSQLiteDatabase database, String query){ 25 | Cursor cursor = database.query(query, new String[]{}); 26 | String value = ""; 27 | if(cursor != null){ 28 | cursor.moveToFirst(); 29 | value = cursor.getString(0); 30 | cursor.close(); 31 | } 32 | return value; 33 | } 34 | 35 | public static int singleIntegerValueFromQuery(SupportSQLiteDatabase database, String query){ 36 | Cursor cursor = database.query(query, new String[]{}); 37 | int value = 0; 38 | if(cursor != null){ 39 | cursor.moveToFirst(); 40 | value = cursor.getInt(0); 41 | cursor.close(); 42 | } 43 | return value; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/ScrollingCursorAdapter.java: -------------------------------------------------------------------------------- 1 | package net.zetetic; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.CursorAdapter; 8 | import android.widget.TextView; 9 | 10 | import net.sqlcipher.Cursor; 11 | 12 | public class ScrollingCursorAdapter extends CursorAdapter { 13 | 14 | public ScrollingCursorAdapter(Context context, Cursor cursor){ 15 | super(context, cursor, 0); 16 | } 17 | 18 | @Override 19 | public View newView(Context context, android.database.Cursor cursor, ViewGroup parent) { 20 | return LayoutInflater.from(context).inflate(R.layout.cursor_item, parent, false); 21 | } 22 | 23 | @Override 24 | public void bindView(View view, Context context, android.database.Cursor cursor) { 25 | TextView messageDisplay = view.findViewById(R.id.message); 26 | String message = cursor.getString (cursor.getColumnIndex("a")); 27 | messageDisplay.setText(message); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/AES128CipherTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.sqlcipher.database.SQLiteDatabaseHook; 6 | import net.zetetic.ZeteticApplication; 7 | 8 | import java.io.File; 9 | 10 | public class AES128CipherTest extends SQLCipherTest { 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | 14 | String actual = ""; 15 | String value = "hey"; 16 | database.execSQL("create table t1(a)"); 17 | database.execSQL("insert into t1(a) values (?)", new Object[]{value}); 18 | Cursor result = database.rawQuery("select * from t1", new String[]{}); 19 | if(result != null){ 20 | result.moveToFirst(); 21 | actual = result.getString(0); 22 | result.close(); 23 | } 24 | return actual.equals(value); 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "AES-128 Bit Cipher Test"; 30 | } 31 | 32 | @Override 33 | protected SQLiteDatabase createDatabase(File databasePath) { 34 | 35 | String password = ZeteticApplication.DATABASE_PASSWORD; 36 | return SQLiteDatabase.openOrCreateDatabase(databasePath, password, null, new SQLiteDatabaseHook() { 37 | 38 | @Override 39 | public void preKey(SQLiteDatabase database) {} 40 | 41 | @Override 42 | public void postKey(SQLiteDatabase database) { 43 | database.rawExecSQL("PRAGMA cipher = 'aes-128-cbc'"); 44 | } 45 | }); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/AccessDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.ZeteticApplication; 6 | 7 | import java.io.File; 8 | 9 | public class AccessDatabaseTest extends SQLCipherTest { 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | database.close(); 13 | try { 14 | int rows = 0; 15 | String filename = "encrypted.db"; 16 | ZeteticApplication.getInstance().extractAssetToDatabaseDirectory(filename); 17 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(filename); 18 | database = SQLiteDatabase.openDatabase(databasePath.getAbsolutePath(), "test", null, SQLiteDatabase.OPEN_READWRITE); 19 | if(database != null){ 20 | Cursor cursor = database.rawQuery("SELECT COUNT(*) FROM sqlite_master;", new Object[]{}); 21 | if(cursor != null){ 22 | cursor.moveToFirst(); 23 | rows = cursor.getInt(0); 24 | cursor.close(); 25 | } 26 | } 27 | return rows > 0; 28 | } catch (Exception e) { 29 | return false; 30 | } 31 | } 32 | 33 | @Override 34 | public String getName() { 35 | return "Access Database File Test"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/AttachDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | import net.zetetic.ZeteticApplication; 7 | 8 | import java.io.File; 9 | 10 | public class AttachDatabaseTest extends SQLCipherTest { 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | boolean status; 14 | String password = "test123"; 15 | File fooDatabase = ZeteticApplication.getInstance().getDatabasePath("foo.db"); 16 | if(fooDatabase.exists()){ 17 | fooDatabase.delete(); 18 | } 19 | database.execSQL("ATTACH database ? AS encrypted KEY ?", new Object[]{fooDatabase.getAbsolutePath(), password}); 20 | database.execSQL("create table encrypted.t1(a,b);"); 21 | database.execSQL("insert into encrypted.t1(a,b) values(?,?);", new Object[]{"one for the money", "two for the show"}); 22 | int rowCount = QueryHelper.singleIntegerValueFromQuery(database, "select count(*) from encrypted.t1;"); 23 | status = rowCount == 1; 24 | database.close(); 25 | return status; 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "Attach database test"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/AttachNewDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.ZeteticApplication; 5 | 6 | import java.io.File; 7 | 8 | public class AttachNewDatabaseTest extends SQLCipherTest { 9 | @Override 10 | public boolean execute(SQLiteDatabase encryptedDatabase) { 11 | 12 | encryptedDatabase.execSQL("create table t1(a,b)"); 13 | encryptedDatabase.execSQL("insert into t1(a,b) values(?, ?)", new Object[]{"one", "two"}); 14 | 15 | String newKey = "foo"; 16 | File newDatabasePath = ZeteticApplication.getInstance().getDatabasePath("normal.db"); 17 | String attachCommand = "ATTACH DATABASE ? as encrypted KEY ?"; 18 | String createCommand = "create table encrypted.t1(a,b)"; 19 | String insertCommand = "insert into encrypted.t1 SELECT * from t1"; 20 | String detachCommand = "DETACH DATABASE encrypted"; 21 | encryptedDatabase.execSQL(attachCommand, new Object[]{newDatabasePath.getAbsolutePath(), newKey}); 22 | encryptedDatabase.execSQL(createCommand); 23 | encryptedDatabase.execSQL(insertCommand); 24 | encryptedDatabase.execSQL(detachCommand); 25 | 26 | return true; 27 | } 28 | 29 | @Override 30 | protected void tearDown(SQLiteDatabase database) { 31 | File newDatabasePath = ZeteticApplication.getInstance().getDatabasePath("normal.db"); 32 | newDatabasePath.delete(); 33 | } 34 | 35 | public android.database.sqlite.SQLiteDatabase createNormalDatabase(){ 36 | File newDatabasePath = ZeteticApplication.getInstance().getDatabasePath("normal.db"); 37 | return android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(newDatabasePath.getAbsolutePath(), null); 38 | } 39 | 40 | @Override 41 | public String getName() { 42 | return "Attach New Database Test"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/BeginTransactionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class BeginTransactionTest extends SQLCipherTest { 6 | @Override 7 | public boolean execute(SQLiteDatabase database) { 8 | database.beginTransaction(); 9 | database.endTransaction(); 10 | return true; 11 | } 12 | 13 | @Override 14 | public String getName() { 15 | return "Begin transaction test"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/BindBooleanRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class BindBooleanRawQueryTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.execSQL("create table t1(a,b);"); 10 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", true}); 11 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{true}); 12 | if(cursor != null){ 13 | if(cursor.moveToFirst()) { 14 | String a = cursor.getString(0); 15 | int b = cursor.getInt(1); 16 | cursor.close(); 17 | return a.equals("one for the money") && b == 1; 18 | } 19 | } 20 | return false; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Bind Boolean for RawQuery Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/BindByteArrayRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | import java.security.SecureRandom; 7 | import java.util.Arrays; 8 | 9 | public class BindByteArrayRawQueryTest extends SQLCipherTest { 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | 13 | SecureRandom random = new SecureRandom(); 14 | byte[] randomData = new byte[20]; 15 | random.nextBytes(randomData); 16 | database.execSQL("create table t1(a,b);"); 17 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", randomData}); 18 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{randomData}); 19 | if(cursor != null){ 20 | if(cursor.moveToFirst()) { 21 | String a = cursor.getString(0); 22 | byte[] b = cursor.getBlob(1); 23 | cursor.close(); 24 | return a.equals("one for the money") && Arrays.equals(randomData, b); 25 | } 26 | } 27 | return false; 28 | } 29 | 30 | @Override 31 | public String getName() { 32 | return "Bind Byte Array for RawQuery Test"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/BindDoubleRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class BindDoubleRawQueryTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.execSQL("create table t1(a,b);"); 10 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", 2.0d}); 11 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{2.0d}); 12 | if(cursor != null){ 13 | if(cursor.moveToFirst()) { 14 | String a = cursor.getString(0); 15 | Double b = cursor.getDouble(1); 16 | cursor.close(); 17 | return a.equals("one for the money") && b == 2.0d; 18 | } 19 | } 20 | return false; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Bind Double for RawQuery Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/BindFloatRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class BindFloatRawQueryTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.execSQL("create table t1(a,b);"); 10 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", 2.25f}); 11 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{2.25f}); 12 | if(cursor != null){ 13 | if(cursor.moveToFirst()) { 14 | String a = cursor.getString(0); 15 | float b = cursor.getFloat(1); 16 | cursor.close(); 17 | return a.equals("one for the money") && b == 2.25f; 18 | } 19 | } 20 | return false; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Bind Float for RawQuery Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/BindLongRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class BindLongRawQueryTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.execSQL("create table t1(a,b);"); 10 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", 2L}); 11 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{2L}); 12 | if(cursor != null){ 13 | if(cursor.moveToFirst()) { 14 | String a = cursor.getString(0); 15 | long b = cursor.getLong(1); 16 | cursor.close(); 17 | return a.equals("one for the money") && b == 2L; 18 | } 19 | } 20 | return false; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Bind Long for RawQuery Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/BindStringRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class BindStringRawQueryTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.execSQL("create table t1(a,b);"); 10 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", "two for the show"}); 11 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{"two for the show"}); 12 | if(cursor != null){ 13 | if(cursor.moveToFirst()) { 14 | String a = cursor.getString(0); 15 | String b = cursor.getString(1); 16 | cursor.close(); 17 | return a.equals("one for the money") && b.equals("two for the show"); 18 | } 19 | } 20 | return false; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Bind String for RawQuery Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CanThrowSQLiteExceptionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import android.database.sqlite.SQLiteException; 5 | 6 | public class CanThrowSQLiteExceptionTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | 11 | try{ 12 | throw new SQLiteException(); 13 | }catch (SQLiteException ex){ 14 | return true; 15 | } 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return "SQLiteException Test"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CheckIsDatabaseIntegrityOkTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class CheckIsDatabaseIntegrityOkTest extends SQLCipherTest { 6 | @Override 7 | public boolean execute(SQLiteDatabase database) { 8 | return database.isDatabaseIntegrityOk(); 9 | } 10 | 11 | @Override 12 | public String getName() { 13 | return "Check Database Integrity"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CheckIsWriteAheadLoggingEnabledTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class CheckIsWriteAheadLoggingEnabledTest extends SQLCipherTest { 6 | @Override 7 | public boolean execute(SQLiteDatabase database) { 8 | database.enableWriteAheadLogging(); 9 | boolean statusWhenEnabled = database.isWriteAheadLoggingEnabled(); 10 | database.disableWriteAheadLogging(); 11 | boolean statusWhenDisabled = database.isWriteAheadLoggingEnabled(); 12 | return statusWhenEnabled && !statusWhenDisabled; 13 | } 14 | 15 | @Override 16 | public String getName() { 17 | return "Test isWriteAheadLoggingEnabled"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CipherMigrateTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.util.Log; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.sqlcipher.database.SQLiteDatabaseHook; 6 | import net.zetetic.QueryHelper; 7 | import net.zetetic.ZeteticApplication; 8 | 9 | import java.io.File; 10 | 11 | public class CipherMigrateTest extends SQLCipherTest { 12 | 13 | File olderFormatDatabase = ZeteticApplication.getInstance().getDatabasePath("2x.db"); 14 | 15 | @Override 16 | public boolean execute(SQLiteDatabase database) { 17 | database.close(); 18 | final boolean[] status = {false}; 19 | try { 20 | ZeteticApplication.getInstance().extractAssetToDatabaseDirectory("2x.db"); 21 | SQLiteDatabaseHook hook = new SQLiteDatabaseHook() { 22 | public void preKey(SQLiteDatabase database) {} 23 | public void postKey(SQLiteDatabase database) { 24 | String value = QueryHelper.singleValueFromQuery(database, "PRAGMA cipher_migrate"); 25 | setMessage(String.format("cipher_migrate result:%s", value)); 26 | status[0] = Integer.valueOf(value) == 0; 27 | } 28 | }; 29 | database = SQLiteDatabase.openDatabase(olderFormatDatabase.getPath(), 30 | ZeteticApplication.DATABASE_PASSWORD, null, 31 | SQLiteDatabase.OPEN_READWRITE | SQLiteDatabase.CREATE_IF_NECESSARY, hook); 32 | if(database != null){ 33 | database.close(); 34 | } 35 | } catch (Exception e) { 36 | Log.i(TAG, "error", e); 37 | } 38 | return status[0]; 39 | } 40 | 41 | @Override 42 | public String getName() { 43 | return "Cipher Migrate Test"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CompileBeginTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class CompileBeginTest extends SQLCipherTest { 6 | 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | try { 10 | database.compileStatement("begin").execute(); 11 | return true; 12 | }catch (Exception e){ 13 | return false; 14 | } 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return "Compile Begin Test"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CompileStatementSyntaxErrorMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.sqlcipher.database.SQLiteStatement; 7 | import android.database.sqlite.SQLiteException; 8 | 9 | import net.zetetic.ZeteticApplication; 10 | 11 | import android.util.Log; 12 | 13 | public class CompileStatementSyntaxErrorMessageTest extends SQLCipherTest { 14 | 15 | @Override 16 | public boolean execute(SQLiteDatabase database) { 17 | try { 18 | SQLiteStatement ignored = database.compileStatement("INSERT INTO mytable (mydata) VALUES"); 19 | } catch (SQLiteException e) { 20 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteException", e); 21 | String message = e.getMessage(); 22 | setMessage(message); 23 | // TBD missing error code etc. 24 | if (!message.matches("incomplete input: , while compiling: INSERT INTO mytable \\(mydata\\) VALUES")) { 25 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 26 | return false; 27 | } 28 | return true; 29 | } catch (Exception e) { 30 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 31 | return false; 32 | } 33 | 34 | return false; 35 | } 36 | 37 | @Override 38 | public String getName() { 39 | return "Compile statement syntax error message Test"; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CompiledSQLUpdateTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.sqlcipher.database.SQLiteStatement; 6 | 7 | public class CompiledSQLUpdateTest extends SQLCipherTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | 11 | database.rawExecSQL("create table ut1(a text, b integer)"); 12 | database.execSQL("insert into ut1(a, b) values (?,?)", new Object[]{"s1", new Integer(100)}); 13 | 14 | SQLiteStatement st = database.compileStatement("update ut1 set b = 101 where b = 100"); 15 | long recs = st.executeUpdateDelete(); 16 | return (recs == 1); 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "Compiled SQL update test"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/ComputeKDFTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.QueryHelper; 6 | 7 | public class ComputeKDFTest extends SQLCipherTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | database.rawExecSQL("PRAGMA cipher_kdf_compute;"); 12 | String kdf = QueryHelper.singleValueFromQuery(database, "PRAGMA kdf_iter;"); 13 | setMessage(String.format("Computed KDF:%s", kdf)); 14 | return true; 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return "Compute KDF Test"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CopyStringToBufferNullTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | 7 | public class CopyStringToBufferNullTest extends SQLCipherTest { 8 | 9 | private CharArrayBuffer charArrayBuffer = null; 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | boolean result = false; 14 | try { 15 | database.execSQL("create table t1(a TEXT, b TEXT);"); 16 | database.execSQL("insert into t1(a,b) values(500, 500);"); 17 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 18 | if(cursor != null){ 19 | cursor.moveToFirst(); 20 | cursor.copyStringToBuffer(0, charArrayBuffer); 21 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 22 | "500".equals(actualValue); 23 | } 24 | } catch (IllegalArgumentException ex){ 25 | result = true; 26 | } finally { 27 | return result; 28 | } 29 | 30 | } 31 | 32 | @Override 33 | public String getName() { 34 | return "Copy String To Buffer Null Test"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CopyStringToBufferTestFloatLargeBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | 7 | public class CopyStringToBufferTestFloatLargeBuffer extends SQLCipherTest { 8 | 9 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(128); 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | 14 | database.execSQL("create table t1(a REAL, b REAL);"); 15 | database.execSQL("insert into t1(a,b) values(123.45, 67.89);"); 16 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 17 | if(cursor != null){ 18 | cursor.moveToFirst(); 19 | cursor.copyStringToBuffer(1, charArrayBuffer); 20 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 21 | return "67.89".equals(actualValue); 22 | } 23 | return false; 24 | 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "Copy String To Buffer Test Float Large Buffer"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CopyStringToBufferTestFloatSmallBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | 7 | public class CopyStringToBufferTestFloatSmallBuffer extends SQLCipherTest { 8 | 9 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(1); 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | 14 | database.execSQL("create table t1(a REAL, b REAL);"); 15 | database.execSQL("insert into t1(a,b) values(123.45, 67.89);"); 16 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 17 | if(cursor != null){ 18 | cursor.moveToFirst(); 19 | cursor.copyStringToBuffer(1, charArrayBuffer); 20 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 21 | return "67.89".equals(actualValue); 22 | } 23 | return false; 24 | 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "Copy String To Buffer Test Float Small Buffer"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CopyStringToBufferTestIntegerLargeBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | 7 | public class CopyStringToBufferTestIntegerLargeBuffer extends SQLCipherTest { 8 | 9 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(128); 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | 14 | database.execSQL("create table t1(a INTEGER, b INTEGER);"); 15 | database.execSQL("insert into t1(a,b) values(123, 456);"); 16 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 17 | if(cursor != null){ 18 | cursor.moveToFirst(); 19 | cursor.copyStringToBuffer(1, charArrayBuffer); 20 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 21 | return "456".equals(actualValue); 22 | } 23 | return false; 24 | 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "Copy String To Buffer Test Integer Large Buffer"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CopyStringToBufferTestIntegerSmallBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | 7 | public class CopyStringToBufferTestIntegerSmallBuffer extends SQLCipherTest { 8 | 9 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(1); 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | 14 | database.execSQL("create table t1(a INTEGER, b INTEGER);"); 15 | database.execSQL("insert into t1(a,b) values(123, 456);"); 16 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 17 | if(cursor != null){ 18 | cursor.moveToFirst(); 19 | cursor.copyStringToBuffer(1, charArrayBuffer); 20 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 21 | return "456".equals(actualValue); 22 | } 23 | return false; 24 | 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "Copy String To Buffer Test Integer Small Buffer"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CopyStringToBufferTestStringLargeBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.CharArrayBuffer; 4 | 5 | import net.sqlcipher.Cursor; 6 | import net.sqlcipher.database.SQLiteDatabase; 7 | 8 | public class CopyStringToBufferTestStringLargeBuffer extends SQLCipherTest { 9 | 10 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(128); 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | database.execSQL("create table t1(a TEXT, b TEXT);"); 15 | database.execSQL("insert into t1(a,b) values(500, 500);"); 16 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 17 | if(cursor != null){ 18 | cursor.moveToFirst(); 19 | cursor.copyStringToBuffer(0, charArrayBuffer); 20 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 21 | return "500".equals(actualValue); 22 | } 23 | return false; 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return "Copy String To Buffer Test String Large Buffer"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CopyStringToBufferTestStringSmallBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | 7 | public class CopyStringToBufferTestStringSmallBuffer extends SQLCipherTest { 8 | 9 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(1); 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | database.execSQL("create table t1(a TEXT, b TEXT);"); 14 | database.execSQL("insert into t1(a,b) values(500, 500);"); 15 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 16 | if(cursor != null){ 17 | cursor.moveToFirst(); 18 | cursor.copyStringToBuffer(0, charArrayBuffer); 19 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 20 | return "500".equals(actualValue); 21 | } 22 | return false; 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return "Copy String To Buffer Test String Small Buffer"; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CreateOpenDatabaseWithByteArrayTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.ZeteticApplication; 6 | 7 | import java.io.File; 8 | 9 | public class CreateOpenDatabaseWithByteArrayTest extends SQLCipherTest { 10 | 11 | private String databaseName = "foo.db"; 12 | 13 | @Override 14 | public boolean execute(SQLiteDatabase database) { 15 | boolean status = false; 16 | database.close(); 17 | byte[] key = generateRandomByteArray(32); 18 | File newDatabasePath = ZeteticApplication.getInstance().getDatabasePath(databaseName); 19 | newDatabasePath.delete(); 20 | database = SQLiteDatabase.openOrCreateDatabase(newDatabasePath.getPath(), key, null); 21 | database.execSQL("create table t1(a,b);"); 22 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{1, 2}); 23 | database.close(); 24 | database = SQLiteDatabase.openOrCreateDatabase(newDatabasePath.getPath(), key, null); 25 | Cursor cursor = database.rawQuery("select * from t1;", null); 26 | if (cursor != null) { 27 | cursor.moveToNext(); 28 | int a = cursor.getInt(0); 29 | int b = cursor.getInt(1); 30 | cursor.close(); 31 | status = a == 1 && b == 2; 32 | } 33 | return status; 34 | } 35 | 36 | @Override 37 | public String getName() { 38 | return "Create/Open with Byte Array Test"; 39 | } 40 | 41 | @Override 42 | protected void tearDown(SQLiteDatabase database) { 43 | super.tearDown(database); 44 | File newDatabasePath = ZeteticApplication.getInstance().getDatabasePath(databaseName); 45 | newDatabasePath.delete(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/CrossProcessCursorQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.app.Activity; 4 | import android.net.Uri; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.zetetic.ZeteticApplication; 7 | import net.zetetic.ZeteticContentProvider; 8 | 9 | public class CrossProcessCursorQueryTest extends SQLCipherTest { 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | 14 | Activity activity = ZeteticApplication.getInstance().getCurrentActivity(); 15 | Uri providerUri = ZeteticContentProvider.CONTENT_URI; 16 | android.database.Cursor cursor = activity.managedQuery(providerUri, null, null, null, null); 17 | StringBuilder buffer = new StringBuilder(); 18 | while (cursor.moveToNext()) { 19 | buffer.append(cursor.getString(0)); 20 | buffer.append(cursor.getString(1)); 21 | } 22 | cursor.close(); 23 | return buffer.toString().length() > 0; 24 | } 25 | 26 | 27 | 28 | @Override 29 | public String getName() { 30 | return "Custom Cross Process Cursor Test"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/DefaultCursorWindowAllocationTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class DefaultCursorWindowAllocationTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | try { 10 | int rowCount = 0; 11 | int rows = 10000; 12 | //final int dataSize = 2048; 13 | final int dataSize = 16384; 14 | buildDatabase(database, rows, 1, new RowColumnValueBuilder() { 15 | @Override 16 | public Object buildRowColumnValue(String[] columns, int row, int column) { 17 | return generateRandomByteArray(dataSize); 18 | } 19 | }); 20 | rows = 1; 21 | Cursor cursor = database.rawQuery("SELECT count(length(a)) FROM t1;", new Object[]{}); 22 | if(cursor == null) return false; 23 | while(cursor.moveToNext()){ 24 | //byte[] data = cursor.getBlob(0); 25 | int size = cursor.getInt(0); 26 | cursor.close(); 27 | // if(data.length != dataSize) { 28 | // cursor.close(); 29 | // return false; 30 | // } 31 | rowCount++; 32 | } 33 | cursor.close(); 34 | return rowCount == rows; 35 | } catch (Exception e){ 36 | String message = String.format("Error:%s", e.getMessage()); 37 | log(message); 38 | setMessage(message); 39 | return false; 40 | } 41 | } 42 | 43 | @Override 44 | public String getName() { 45 | return "Default cursor window allocation test"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/DeleteFunctionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class DeleteFunctionTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | 10 | boolean status = false; 11 | database.rawExecSQL("create table t1(itemId TEXT UNIQUE, userId INTEGER);"); 12 | database.execSQL("insert into t1(itemId, userId) values(?, ?);", new Object[]{"123", 456}); 13 | int currentCount = getCurrentCount(database, "123", 456); 14 | if(currentCount != 1) { 15 | setMessage("Initial insert failed"); 16 | return status; 17 | } 18 | database.delete("t1", "itemId = ? and userId = ?", new String[]{"123", String.valueOf(456)}); 19 | currentCount = getCurrentCount(database, "123", 456); 20 | status = currentCount == 0; 21 | return status; 22 | } 23 | 24 | private int getCurrentCount(SQLiteDatabase database, String itemId, int userId) { 25 | int count = 0; 26 | try { 27 | Cursor cursor = database.rawQuery("select count(*) from t1 where itemId = ? and userId = ?;", 28 | new String[]{itemId, String.valueOf(userId)}); 29 | if(cursor != null){ 30 | cursor.moveToFirst(); 31 | count = cursor.getInt(0); 32 | cursor.close(); 33 | } 34 | } 35 | catch (Exception ex){} 36 | finally { 37 | return count; 38 | } 39 | } 40 | 41 | @Override 42 | public String getName() { 43 | return "Delete Function Test"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/DeleteTableWithNullWhereArgsTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class DeleteTableWithNullWhereArgsTest extends SQLCipherTest { 6 | @Override 7 | public boolean execute(SQLiteDatabase database) { 8 | String[] args = null; 9 | int rowsDeleted = 0; 10 | database.rawExecSQL("create table t1(a,b);"); 11 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{1, 2}); 12 | rowsDeleted = database.delete("t1", "a = 1", args); 13 | return rowsDeleted == 1; 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "Delete Table Test"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/DisableWriteAheadLoggingTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | public class DisableWriteAheadLoggingTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | boolean result = database.enableWriteAheadLogging(); 10 | String currentMode = getJournalModeState(database); 11 | if(!result || !currentMode.equals("wal")) return false; 12 | database.disableWriteAheadLogging(); 13 | currentMode = getJournalModeState(database); 14 | return currentMode.equals("delete"); 15 | } 16 | 17 | private String getJournalModeState(SQLiteDatabase database){ 18 | return QueryHelper.singleValueFromQuery(database, "PRAGMA journal_mode;"); 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "Disable WAL mode"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/EnableForeignKeyConstraintsTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | public class EnableForeignKeyConstraintsTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | String initialState = getForeignKeyState(database); 10 | if(!initialState.equals("0")) return false; 11 | database.setForeignKeyConstraintsEnabled(true); 12 | String currentState = getForeignKeyState(database); 13 | if(!currentState.equals("1")) return false; 14 | return true; 15 | } 16 | 17 | private String getForeignKeyState(SQLiteDatabase database){ 18 | return QueryHelper.singleValueFromQuery(database, "PRAGMA foreign_keys"); 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "Enable Foreign Key Constraints"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/EnableForeignKeySupportTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | public class EnableForeignKeySupportTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | String defaultValue = QueryHelper.singleValueFromQuery(database, "PRAGMA foreign_keys"); 10 | database.rawExecSQL("PRAGMA foreign_keys = ON;"); 11 | String updatedValue = QueryHelper.singleValueFromQuery(database, "PRAGMA foreign_keys"); 12 | return defaultValue.equals("0") && updatedValue.equals("1"); 13 | } 14 | 15 | @Override 16 | public String getName() { 17 | return "Enable Foreign Key Support Test"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/EnableWriteAheadLoggingTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | public class EnableWriteAheadLoggingTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | boolean result = database.enableWriteAheadLogging(); 10 | String currentMode = QueryHelper.singleValueFromQuery(database, "PRAGMA journal_mode;"); 11 | return result && currentMode.equals("wal"); 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "Enable WAL mode"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/ExecuteInsertConstraintErrorMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.sqlcipher.database.SQLiteStatement; 7 | import android.database.sqlite.SQLiteConstraintException; 8 | 9 | import net.zetetic.ZeteticApplication; 10 | 11 | import android.util.Log; 12 | 13 | public class ExecuteInsertConstraintErrorMessageTest extends SQLCipherTest { 14 | 15 | @Override 16 | public boolean execute(SQLiteDatabase database) { 17 | database.execSQL("CREATE TABLE tt(a UNIQUE, b)"); 18 | database.execSQL("INSERT INTO tt VALUES (101, 'Alice')"); 19 | try { 20 | SQLiteStatement insertStatement = database.compileStatement("INSERT INTO tt VALUES (101, 'Betty')"); 21 | long ignored = insertStatement.executeInsert(); 22 | } catch (SQLiteConstraintException e) { 23 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteConstraintException", e); 24 | String message = e.getMessage(); 25 | setMessage(message); 26 | if (!message.matches("error code 19 \\(extended error code 2067\\): UNIQUE constraint failed: tt\\.a")) { 27 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 28 | return false; 29 | } 30 | return true; 31 | } catch (Exception e) { 32 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 33 | return false; 34 | } 35 | 36 | return false; 37 | } 38 | 39 | @Override 40 | public String getName() { 41 | return "Execute insert constraint error message Test"; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/FIPSTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | public class FIPSTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | 10 | String version = QueryHelper.singleValueFromQuery(database, "PRAGMA cipher_version;"); 11 | setMessage(String.format("SQLCipher version:%s", version)); 12 | int expectedValue = version.contains("FIPS") ? 1 : 0; 13 | 14 | int status = QueryHelper.singleIntegerValueFromQuery(database, "PRAGMA cipher_fips_status;"); 15 | return status == expectedValue; 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return "FIPS Test"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/FTS5Test.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class FTS5Test extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.execSQL("CREATE VIRTUAL TABLE email USING fts5(sender, title, body);"); 10 | database.execSQL("insert into email(sender, title, body) values(?, ?, ?);", 11 | new Object[]{"foo@bar.com", "Test Email", "This is a test email message."}); 12 | Cursor cursor = database.rawQuery("select * from email where email match ?;", new String[]{"test"}); 13 | if(cursor != null){ 14 | cursor.moveToFirst(); 15 | return cursor.getString(cursor.getColumnIndex("sender")).equals("foo@bar.com"); 16 | } 17 | return false; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return "FTS5 Test"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/FixedCursorWindowAllocationTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.CursorWindow; 5 | import net.sqlcipher.CursorWindowAllocation; 6 | import net.sqlcipher.CustomCursorWindowAllocation; 7 | import net.sqlcipher.database.SQLiteDatabase; 8 | 9 | public class FixedCursorWindowAllocationTest extends SQLCipherTest { 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | try { 14 | int rowCount = 0; 15 | int rows = 100; 16 | long allocationSize = 1024; 17 | final int dataSize = 491; 18 | CursorWindowAllocation fixedAllocation = new CustomCursorWindowAllocation(allocationSize, 0, allocationSize); 19 | CursorWindow.setCursorWindowAllocation(fixedAllocation); 20 | buildDatabase(database, rows, 1, new RowColumnValueBuilder() { 21 | @Override 22 | public Object buildRowColumnValue(String[] columns, int row, int column) { 23 | return generateRandomByteArray(dataSize); 24 | } 25 | }); 26 | 27 | Cursor cursor = database.rawQuery("SELECT * FROM t1;", new Object[]{}); 28 | if(cursor == null) return false; 29 | while(cursor.moveToNext()){ 30 | byte[] data = cursor.getBlob(0); 31 | if(data.length != dataSize) { 32 | cursor.close(); 33 | return false; 34 | } 35 | rowCount++; 36 | } 37 | cursor.close(); 38 | return rowCount == rows; 39 | } catch (Exception e){ 40 | String message = String.format("Error:%s", e.getMessage()); 41 | log(message); 42 | setMessage(message); 43 | return false; 44 | } 45 | } 46 | 47 | @Override 48 | public String getName() { 49 | return "Small Cursor Window Allocation Test"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/ForeignKeyConstraintsEnabledWithTransactionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class ForeignKeyConstraintsEnabledWithTransactionTest extends SQLCipherTest { 6 | @Override 7 | public boolean execute(SQLiteDatabase database) { 8 | database.beginTransaction(); 9 | try { 10 | database.setForeignKeyConstraintsEnabled(true); 11 | }catch (IllegalStateException ex){ 12 | if(ex.getMessage().equals("Foreign key constraints may not be changed while in a transaction")) { 13 | return true; 14 | } 15 | } 16 | return false; 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "Disallow foreign key constraints in transaction"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/FullTextSearchTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class FullTextSearchTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | 11 | database.execSQL("CREATE VIRTUAL TABLE sites USING fts4(domain, url, title, meta_keys, body)"); 12 | database.execSQL("CREATE TABLE keywords (keyword TEXT)"); 13 | 14 | database.execSQL("insert into sites(domain, url, title, meta_keys, body) values(?, ?, ?, ?, ?)", 15 | new Object[]{"sqlcipher.net", "http://sqlcipher.net", 16 | "Home - SQLCipher - Open Source Full Database Encryption for SQLite", 17 | "sqlcipher, sqlite", ""}); 18 | database.execSQL("insert into keywords(keyword) values(?)", new Object[]{"SQLCipher"}); 19 | database.execSQL("insert into keywords(keyword) values(?)", new Object[]{"SQLite"}); 20 | 21 | String query = "SELECT keyword FROM keywords INNER JOIN sites ON sites.title MATCH keywords.keyword"; 22 | Cursor result = database.rawQuery(query, new String[]{}); 23 | int resultCount = 0; 24 | while (result.moveToNext()){ 25 | String row = result.getString(0); 26 | if(row != null){ 27 | resultCount++; 28 | } 29 | } 30 | result.close(); 31 | return resultCount > 0; 32 | } 33 | 34 | @Override 35 | public String getName() { 36 | return "Full Text Search Test"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/GetAttachedDatabasesTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.util.Pair; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.zetetic.ZeteticApplication; 7 | 8 | import java.io.File; 9 | import java.util.List; 10 | import java.util.UUID; 11 | 12 | public class GetAttachedDatabasesTest extends SQLCipherTest { 13 | @Override 14 | public boolean execute(SQLiteDatabase database) { 15 | UUID id = UUID.randomUUID(); 16 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(id.toString()); 17 | List> attached = database.getAttachedDbs(); 18 | boolean initialAttach = attached.size() == 1 && attached.get(0).first.equals("main"); 19 | database.execSQL("ATTACH database ? as foo;", 20 | new Object[]{databasePath.getAbsolutePath()}); 21 | attached = database.getAttachedDbs(); 22 | return initialAttach && attached.size() == 2; 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return "Get Attached Databases Test"; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/GetTypeFromCrossProcessCursorWrapperTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class GetTypeFromCrossProcessCursorWrapperTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table t1(a,b);"); 11 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", "two for the show"}); 12 | Cursor cursor = database.query("t1", new String[]{"a", "b"}, null, null, null, null, null); 13 | cursor.moveToFirst(); 14 | int type_a = cursor.getType(0); 15 | int type_b = cursor.getType(1); 16 | cursor.close(); 17 | database.close(); 18 | return (type_a == Cursor.FIELD_TYPE_STRING) && (type_b == Cursor.FIELD_TYPE_STRING); 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "Get Type from CrossProcessCursorWrapper"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/ICUTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class ICUTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | String expected = "КАКОЙ-ТО КИРИЛЛИЧЕСКИЙ ТЕКСТ"; // SOME Cyrillic TEXT 10 | String actual = ""; 11 | 12 | Cursor result = database.rawQuery("select UPPER('Какой-то кириллический текст') as u1", new String[]{}); 13 | if (result != null) { 14 | result.moveToFirst(); 15 | actual = result.getString(0); 16 | result.close(); 17 | } 18 | return actual.equals(expected); 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "ICU Test"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/InsertWithOnConflictTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.content.ContentValues; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class InsertWithOnConflictTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.execSQL("create table user(_id integer primary key autoincrement, email text unique not null);"); 10 | ContentValues values = new ContentValues(); 11 | values.put("email", "foo@bar.com"); 12 | long id = database.insertWithOnConflict("user", null, values, 13 | SQLiteDatabase.CONFLICT_IGNORE); 14 | long error = database.insertWithOnConflict("user", null, values, 15 | SQLiteDatabase.CONFLICT_IGNORE); 16 | return id == 1 && error == -1; 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "Insert with OnConflict"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/InterprocessBlobQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.app.Activity; 4 | import android.net.Uri; 5 | 6 | import net.sqlcipher.database.SQLiteDatabase; 7 | import net.zetetic.ZeteticApplication; 8 | import net.zetetic.ZeteticContentProvider2; 9 | 10 | public class InterprocessBlobQueryTest extends SQLCipherTest { 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | 15 | Activity activity = ZeteticApplication.getInstance().getCurrentActivity(); 16 | Uri providerUri = ZeteticContentProvider2.CONTENT_URI; 17 | android.database.Cursor cursor = activity.getContentResolver().query(providerUri, null, null, null, null); 18 | StringBuilder buffer = new StringBuilder(); 19 | while (cursor.moveToNext()) { 20 | buffer.append(cursor.getString(0)); 21 | buffer.append(new String(cursor.getBlob(1))); 22 | } 23 | cursor.close(); 24 | return buffer.toString().length() > 0; 25 | } 26 | 27 | 28 | 29 | @Override 30 | public String getName() { 31 | return "Custom Inter-Process Blob Test"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/JavaClientLibraryVersionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class 6 | JavaClientLibraryVersionTest extends SQLCipherTest { 7 | 8 | private final String EXPECTED_SQLCIPHER_ANDROID_VERSION = "4.5.4"; 9 | 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | setMessage(String.format("Report:%s", SQLiteDatabase.SQLCIPHER_ANDROID_VERSION)); 13 | return SQLiteDatabase.SQLCIPHER_ANDROID_VERSION.equals(EXPECTED_SQLCIPHER_ANDROID_VERSION); 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "Java Client Library Version Test"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/JsonCastTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class JsonCastTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | String name = "Bob Smith", queryName = ""; 10 | String query = String.format("select cast(json_extract('{\"user\":\"%s\"}','$.user') as TEXT);", name); 11 | Cursor cursor = database.rawQuery(query, new Object[]{}); 12 | if(cursor != null && cursor.moveToFirst()){ 13 | queryName = cursor.getString(0); 14 | cursor.close(); 15 | } 16 | return name.equals(queryName); 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "JSON cast test"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/LoopingCountQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class LoopingCountQueryTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | int counter = 0; 11 | int iterations = 10; 12 | database.execSQL("create table t1(a);"); 13 | database.execSQL("insert into t1(a) values (?)", new Object[]{"foo"}); 14 | StringBuilder buffer = new StringBuilder(); 15 | while(counter < iterations){ 16 | Cursor cursor = database.rawQuery("select count(*) from t1", null); 17 | if(cursor != null){ 18 | cursor.moveToFirst(); 19 | buffer.append(cursor.getInt(0)); 20 | cursor.close(); 21 | } 22 | counter++; 23 | } 24 | return buffer.toString().length() > 0; 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "Looping Count Query Test"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/LoopingInsertTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.util.Log; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | 7 | public class LoopingInsertTest extends SQLCipherTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("CREATE TABLE some_table(name TEXT, surname TEXT);"); 11 | long startTime = System.currentTimeMillis(); 12 | database.execSQL("begin;"); 13 | for(int index = 0; index < 10000; index++){ 14 | database.execSQL("insert into some_table(name, surname) values(?, ?)", 15 | new Object[]{"one for the money", "two for the show"}); 16 | } 17 | database.execSQL("commit;"); 18 | long diff = System.currentTimeMillis() - startTime; 19 | Log.e(TAG, String.format("Inserted in: %d ms", diff)); 20 | return true; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Looping Insert Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/LoopingQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class LoopingQueryTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | int counter = 0; 11 | int iterations = 1000; 12 | database.execSQL("create table t1(a);"); 13 | database.execSQL("insert into t1(a) values (?)", new Object[]{"foo"}); 14 | StringBuilder buffer = new StringBuilder(); 15 | while(counter < iterations){ 16 | Cursor cursor = database.rawQuery("select * from t1", null); 17 | if(cursor != null){ 18 | cursor.moveToFirst(); 19 | buffer.append(cursor.getString(0)); 20 | cursor.close(); 21 | } 22 | counter++; 23 | } 24 | return buffer.toString().length() > 0; 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "Looping Query Test"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/NestedTransactionsTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | 7 | public class NestedTransactionsTest extends SQLCipherTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | database.rawExecSQL("savepoint foo;"); 12 | database.rawExecSQL("create table t1(a,b);"); 13 | database.execSQL("insert into t1(a,b) values(?,?);", new Object[]{"one for the money", "two for the show"}); 14 | database.rawExecSQL("savepoint bar;"); 15 | database.execSQL("insert into t1(a,b) values(?,?);", new Object[]{"three to get ready", "go man go"}); 16 | database.rawExecSQL("rollback transaction to bar;"); 17 | database.rawExecSQL("commit;"); 18 | int count = QueryHelper.singleIntegerValueFromQuery(database, "select count(*) from t1;"); 19 | return count == 1; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return "Nested Transactions Test"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/NullQueryResultTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class NullQueryResultTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | 11 | database.execSQL("create table t1(a,b);"); 12 | database.execSQL("insert into t1(a,b) values (?, ?)", new Object[]{"foo", null}); 13 | database.execSQL("insert into t1(a,b) values (?, ?)", new Object[]{"bar", null}); 14 | Cursor cursor = database.rawQuery("select a from t1", null); 15 | StringBuilder buffer = new StringBuilder(); 16 | while(cursor.moveToNext()){ 17 | buffer.append(cursor.getString(0)); 18 | } 19 | cursor.close(); 20 | return buffer.toString().length() > 0; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Null Query Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/NullRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class NullRawQueryTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.execSQL("create table t1(a,b);"); 10 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", "two for the show"}); 11 | Cursor cursor = database.rawQuery("select * from t1;", null); 12 | if(cursor != null){ 13 | if(cursor.moveToFirst()) { 14 | String a = cursor.getString(0); 15 | String b = cursor.getString(1); 16 | cursor.close(); 17 | return a.equals("one for the money") && b.equals("two for the show"); 18 | } 19 | } 20 | 21 | 22 | return false; 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return "Bind Null Raw Query Test"; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/OpenReadOnlyDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.ZeteticApplication; 5 | 6 | import java.io.File; 7 | 8 | public class OpenReadOnlyDatabaseTest extends SQLCipherTest { 9 | 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | database.close(); 13 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(ZeteticApplication.DATABASE_NAME); 14 | database = SQLiteDatabase.openDatabase(databasePath.getAbsolutePath(), ZeteticApplication.DATABASE_PASSWORD, 15 | null, SQLiteDatabase.OPEN_READONLY); 16 | boolean opened = database.isOpen(); 17 | database.close(); 18 | return opened; 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "Open Read Only Database Test"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/OpenSQLCipher3DatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.sqlcipher.database.SQLiteDatabaseHook; 6 | import net.zetetic.ZeteticApplication; 7 | 8 | import java.io.File; 9 | 10 | public class OpenSQLCipher3DatabaseTest extends SQLCipherTest { 11 | 12 | String databaseFile = "sqlcipher-3.0-testkey.db"; 13 | 14 | @Override 15 | public boolean execute(SQLiteDatabase database) { 16 | boolean result = false; 17 | try { 18 | database.close(); 19 | SQLiteDatabaseHook hook = new SQLiteDatabaseHook() { 20 | public void preKey(SQLiteDatabase database) {} 21 | public void postKey(SQLiteDatabase database) { 22 | database.execSQL("PRAGMA kdf_iter = 64000;"); 23 | database.execSQL("PRAGMA cipher_page_size = 1024;"); 24 | database.execSQL("PRAGMA cipher_hmac_algorithm = HMAC_SHA1;"); 25 | database.execSQL("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1;"); 26 | } 27 | }; 28 | ZeteticApplication.getInstance().extractAssetToDatabaseDirectory(databaseFile); 29 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(databaseFile); 30 | database = SQLiteDatabase.openDatabase(databasePath.getAbsolutePath(), "testkey", 31 | null, SQLiteDatabase.OPEN_READWRITE, hook); 32 | Cursor cursor = database.rawQuery("SELECT COUNT(*) FROM sqlite_master;", null); 33 | if(cursor != null){ 34 | cursor.moveToFirst(); 35 | int count = cursor.getInt(0); 36 | result = count > 0; 37 | } 38 | } catch (Exception ex) {} 39 | return result; 40 | } 41 | 42 | @Override 43 | public String getName() { 44 | return "Open SQLCipher 3 Database"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/PragmaCipherVersionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | import android.util.Log; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | 7 | public class PragmaCipherVersionTest extends SQLCipherTest { 8 | 9 | private final String CURRENT_CIPHER_VERSION = "4.5.4"; 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | 14 | Log.i(TAG, "Before rawQuery"); 15 | Cursor cursor = database.rawQuery("PRAGMA cipher_version", new String[]{}); 16 | Log.i(TAG, "After rawQuery"); 17 | if(cursor != null){ 18 | Log.i(TAG, "Before cursor.moveToNext()"); 19 | cursor.moveToNext(); 20 | Log.i(TAG, "Before cursor.getString(0)"); 21 | String cipherVersion = cursor.getString(0); 22 | Log.i(TAG, "Before cursor.close"); 23 | cursor.close(); 24 | setMessage(String.format("Reported:%s", cipherVersion)); 25 | return cipherVersion.contains(CURRENT_CIPHER_VERSION); 26 | } 27 | return false; 28 | } 29 | 30 | @Override 31 | public String getName() { 32 | return "PRAGMA cipher_version Test"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/PreventUpdateWithNullWhereArgsFromThrowingExceptionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.content.ContentValues; 4 | import android.database.Cursor; 5 | 6 | import net.sqlcipher.database.SQLiteDatabase; 7 | 8 | class PreventUpdateWithNullWhereArgsFromThrowingExceptionTest extends SQLCipherTest { 9 | 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | try { 13 | database.execSQL("create table t1(a,b);"); 14 | database.execSQL("insert into t1(a,b) values(?, ?)", new Object[]{"foo", "bar"}); 15 | ContentValues values = new ContentValues(); 16 | values.put("b", "baz"); 17 | database.update("t1", SQLiteDatabase.CONFLICT_ABORT, values, null, null); 18 | long count = 0; 19 | Cursor cursor = database.query("select count(*) from t1 where b = ?;", new Object[]{"baz"}); 20 | if(cursor != null && cursor.moveToNext()){ 21 | count = cursor.getLong(0); 22 | } 23 | return count == 1; 24 | } 25 | catch (Exception ex){ 26 | return false; 27 | } 28 | } 29 | 30 | @Override 31 | public String getName() { 32 | return "Prevent update with null where args from throwing"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/QueryDataSizeTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.sqlcipher.database.SQLiteQueryStats; 5 | 6 | public class QueryDataSizeTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.execSQL("CREATE TABLE t1(a,b);"); 10 | database.execSQL("INSERT INTO t1(a,b) VALUES(?, ?);", 11 | new Object[]{generateRandomByteArray(256), generateRandomByteArray(256)}); 12 | database.execSQL("INSERT INTO t1(a,b) VALUES(?, ?);", 13 | new Object[]{generateRandomByteArray(1024), generateRandomByteArray(64)}); 14 | SQLiteQueryStats result = database.getQueryStats("SELECT * FROM t1;", new Object[]{}); 15 | return result.getTotalQueryResultSize() > 0 && result.getLargestIndividualRowSize() > 0; 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return "Query Data Size Test"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/QueryFloatToStringTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | public class QueryFloatToStringTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | String value = QueryHelper.singleValueFromQuery(database, "SELECT 42.09;"); 10 | return value.equals("42.09"); 11 | } 12 | 13 | @Override 14 | public String getName() { 15 | return "Query Float to String"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/QueryIntegerToStringTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | public class QueryIntegerToStringTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | String value = QueryHelper.singleValueFromQuery(database, "SELECT 123;"); 10 | return value.equals("123"); 11 | } 12 | 13 | @Override 14 | public String getName() { 15 | return "Query Integer to String"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/RTreeTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class RTreeTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | int id = 0; 10 | String create = "CREATE VIRTUAL TABLE demo_index USING rtree(id, minX, maxX, minY, maxY);"; 11 | String insert = "INSERT INTO demo_index VALUES(?, ?, ?, ?, ?);"; 12 | database.execSQL(create); 13 | database.execSQL(insert, new Object[]{1, -80.7749, -80.7747, 35.3776, 35.3778}); 14 | Cursor cursor = database.rawQuery("SELECT * FROM demo_index WHERE maxY < ?;", 15 | new Object[]{36}); 16 | if(cursor != null){ 17 | cursor.moveToNext(); 18 | id = cursor.getInt(0); 19 | cursor.close(); 20 | } 21 | return id == 1; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "RTree Test"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/RawExecSQLExceptionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import android.database.sqlite.SQLiteException; 5 | 6 | import net.zetetic.ZeteticApplication; 7 | 8 | import android.util.Log; 9 | 10 | public class RawExecSQLExceptionTest extends SQLCipherTest { 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | 15 | try { 16 | database.rawExecSQL("select foo from bar"); 17 | } catch (SQLiteException e) { 18 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteException", e); 19 | String message = e.getMessage(); 20 | setMessage(message); 21 | if (!message.matches("no such table: bar")) { 22 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 23 | return false; 24 | } 25 | return true; 26 | } catch (Exception e) { 27 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 28 | return false; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | @Override 35 | public String getName() { 36 | return "rawExecSQL Exception Test"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/RawExecSQLTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class RawExecSQLTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | 10 | String actual = ""; 11 | String value = "hey"; 12 | database.rawExecSQL("create table t1(a)"); 13 | database.execSQL("insert into t1(a) values (?)", new Object[]{value}); 14 | Cursor result = database.rawQuery("select * from t1", new String[]{}); 15 | if(result != null){ 16 | result.moveToFirst(); 17 | actual = result.getString(0); 18 | result.close(); 19 | } 20 | return actual.equals(value); 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "rawExecSQL Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/RawQueryNoSuchFunctionErrorMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import android.database.sqlite.SQLiteException; 7 | 8 | import net.zetetic.ZeteticApplication; 9 | 10 | import android.util.Log; 11 | 12 | public class RawQueryNoSuchFunctionErrorMessageTest extends SQLCipherTest { 13 | 14 | @Override 15 | public boolean execute(SQLiteDatabase database) { 16 | try { 17 | Cursor ignored = database.rawQuery("SELECT UPER('Test')", null); 18 | } catch (SQLiteException e) { 19 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteException", e); 20 | String message = e.getMessage(); 21 | setMessage(message); 22 | // TBD missing error code etc. 23 | if (!message.matches("no such function: UPER: .*\\, while compiling: SELECT UPER\\('Test'\\)")) { 24 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 25 | return false; 26 | } 27 | return true; 28 | } catch (Exception e) { 29 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 30 | return false; 31 | } 32 | 33 | return false; 34 | } 35 | 36 | @Override 37 | public String getName() { 38 | return "rawQuery no such function error message Test"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/RawQueryNonsenseStatementErrorMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import android.database.sqlite.SQLiteException; 7 | 8 | import net.zetetic.ZeteticApplication; 9 | 10 | import android.util.Log; 11 | 12 | import java.util.regex.Pattern; 13 | 14 | public class RawQueryNonsenseStatementErrorMessageTest extends SQLCipherTest { 15 | 16 | @Override 17 | public boolean execute(SQLiteDatabase database) { 18 | try { 19 | Cursor ignored = database.rawQuery("101", null); 20 | } catch (SQLiteException e) { 21 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteException", e); 22 | String message = e.getMessage(); 23 | setMessage(message); 24 | // TBD missing error code etc. 25 | if (!message.matches("near \"101\": syntax error: .*\\, while compiling: 101")) { 26 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 27 | return false; 28 | } 29 | return true; 30 | } catch (Exception e) { 31 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 32 | return false; 33 | } 34 | 35 | return false; 36 | } 37 | 38 | @Override 39 | public String getName() { 40 | return "rawQuery nonsense statement error message Test"; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/RawQuerySyntaxErrorMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import android.database.sqlite.SQLiteException; 7 | 8 | import net.zetetic.ZeteticApplication; 9 | 10 | import android.util.Log; 11 | 12 | public class RawQuerySyntaxErrorMessageTest extends SQLCipherTest { 13 | 14 | @Override 15 | public boolean execute(SQLiteDatabase database) { 16 | try { 17 | Cursor ignored = database.rawQuery("SLCT 1", null); 18 | } catch (SQLiteException e) { 19 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteException", e); 20 | String message = e.getMessage(); 21 | setMessage(message); 22 | // TBD missing error code etc. 23 | if (!message.matches("near \"SLCT\": syntax error: .*\\, while compiling: SLCT 1")) { 24 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 25 | return false; 26 | } 27 | return true; 28 | } catch (Exception e) { 29 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 30 | return false; 31 | } 32 | 33 | return false; 34 | } 35 | 36 | @Override 37 | public String getName() { 38 | return "rawQuery syntax error message Test"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/RawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class RawQueryTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | int rows = 0; 11 | database.execSQL("create table t1(a,b);"); 12 | database.execSQL("insert into t1(a,b) values(?, ?);", 13 | new Object[]{"one for the money", "two for the show"}); 14 | Cursor cursor = database.rawQuery("select * from t1;", null, 1, 1); 15 | if(cursor != null){ 16 | while(cursor.moveToNext()) { 17 | cursor.getString(0); 18 | rows++; 19 | } 20 | cursor.close(); 21 | } 22 | return rows > 0; 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return "Raw Query Test"; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/RawRekeyTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.util.Log; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.QueryHelper; 6 | import net.zetetic.ZeteticApplication; 7 | 8 | import java.io.File; 9 | 10 | public class RawRekeyTest extends SQLCipherTest { 11 | 12 | String password = "x\'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99\'"; 13 | String rekeyCommand = String.format("PRAGMA rekey = \"%s\";", password); 14 | File databaseFile = ZeteticApplication.getInstance().getDatabasePath(ZeteticApplication.DATABASE_NAME); 15 | 16 | @Override 17 | public boolean execute(SQLiteDatabase database) { 18 | database.execSQL("create table t1(a,b);"); 19 | database.execSQL("insert into t1(a,b) values(?,?)", new Object[]{"one for the money", "two for the show"}); 20 | database.rawExecSQL(rekeyCommand); 21 | database.close(); 22 | database = SQLiteDatabase.openOrCreateDatabase(databaseFile, password, null); 23 | int count = QueryHelper.singleIntegerValueFromQuery(database, "select count(*) from t1;"); 24 | boolean status = count == 1; 25 | database.close(); 26 | return status; 27 | } 28 | 29 | @Override 30 | public String getName() { 31 | return "Raw Rekey Test"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/ReadWriteUserVersionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class ReadWriteUserVersionTest extends SQLCipherTest { 6 | @Override 7 | public boolean execute(SQLiteDatabase database) { 8 | int version = 4; 9 | database.setVersion(version); 10 | int readVersion = database.getVersion(); 11 | return version == readVersion; 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "Read/write user_version"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/ReadWriteWriteAheadLoggingTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.CursorWindow; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | 7 | public class ReadWriteWriteAheadLoggingTest extends SQLCipherTest { 8 | @Override 9 | public boolean execute(final SQLiteDatabase database) { 10 | 11 | try { 12 | final int[] a = new int[1]; 13 | final int[] b = new int[1]; 14 | database.setLockingEnabled(false); 15 | boolean walEnabled = database.enableWriteAheadLogging(); 16 | if (!walEnabled) return false; 17 | 18 | //database.execSQL("PRAGMA read_uncommitted = 1;"); 19 | 20 | database.execSQL("CREATE TABLE t1(a,b)"); 21 | database.rawQuery("INSERT INTO t1(a,b) VALUES(?,?);", new Object[]{1, 2}); 22 | database.beginTransaction(); 23 | //database.beginTransactionNonExclusive(); 24 | database.rawQuery("DELETE FROM t1 WHERE a = ?;", new Object[]{1}); 25 | Thread t = new Thread(new Runnable() { 26 | @Override 27 | public void run() { 28 | Cursor cursor = database.rawQuery("SELECT COUNT(*) FROM t1 WHERE a = ?;", new Object[]{1}); 29 | if (cursor != null && cursor.moveToFirst()) { 30 | a[0] = cursor.getInt(0); 31 | b[0] = cursor.getInt(0); 32 | log(String.format("Retrieved %d rows back", a[0])); 33 | } 34 | } 35 | }); 36 | t.start(); 37 | t.join(); 38 | database.setTransactionSuccessful(); 39 | database.endTransaction(); 40 | //return a[0] == 1 && b[0] == 2; 41 | return a[0] == 0 && b[0] == 0; 42 | } catch (InterruptedException ex){ 43 | return false; 44 | } 45 | } 46 | 47 | @Override 48 | public String getName() { 49 | return "Read/Write WAL Test"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/ResetQueryCacheFinalizesSqlStatementAndReleasesReferenceTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | class ResetQueryCacheFinalizesSqlStatementAndReleasesReferenceTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | int initialColumnCount = 0, updatedColumnCount = 0; 10 | int initialExpectedColumnCount = 2; 11 | int updatedColumnExpectedCount = 3; 12 | database.execSQL("create table t1(a, b);"); 13 | database.execSQL("insert into t1(a,b) values(?, ?);", 14 | new Object[]{"foo", "bar"}); 15 | Cursor cursor = database.query("t1", null,null,null,null,null,null); 16 | if(cursor != null && cursor.moveToNext()){ 17 | initialColumnCount = cursor.getColumnCount(); 18 | cursor.close(); 19 | } 20 | database.resetCompiledSqlCache(); 21 | database.execSQL("alter table t1 add c text null;"); 22 | cursor = database.query("t1", null,null,null,null,null,null); 23 | if(cursor != null && cursor.moveToNext()){ 24 | updatedColumnCount = cursor.getColumnCount(); 25 | cursor.close(); 26 | } 27 | return initialColumnCount == initialExpectedColumnCount 28 | && updatedColumnCount == updatedColumnExpectedCount; 29 | } 30 | 31 | @Override 32 | public String getName() { 33 | return "Reset Query cache"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/ResultNotifier.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | public interface ResultNotifier { 4 | void send(TestResult result); 5 | void complete(); 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/RowColumnValueBuilder.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | public interface RowColumnValueBuilder { 4 | Object buildRowColumnValue(String[] columns, int row, int column); 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/SQLiteOpenHelperConfigureTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.content.Context; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.sqlcipher.database.SQLiteOpenHelper; 7 | import net.zetetic.ZeteticApplication; 8 | 9 | import java.io.File; 10 | import java.util.UUID; 11 | 12 | public class SQLiteOpenHelperConfigureTest extends SQLCipherTest { 13 | @Override 14 | public boolean execute(SQLiteDatabase database) { 15 | 16 | UUID name = UUID.randomUUID(); 17 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(name.toString()); 18 | ConfigureHelper helper = new ConfigureHelper(ZeteticApplication.getInstance(), 19 | databasePath.getAbsolutePath()); 20 | helper.getWritableDatabase("foo"); 21 | return helper.onConfigureCalled; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "SQLiteOpenHelper Configure Test"; 27 | } 28 | 29 | class ConfigureHelper extends SQLiteOpenHelper { 30 | 31 | public boolean onConfigureCalled = false; 32 | 33 | public ConfigureHelper(Context context, String databasePath) { 34 | super(context, ZeteticApplication.DATABASE_NAME, null, 1); 35 | } 36 | 37 | public void onConfigure(SQLiteDatabase database){ 38 | onConfigureCalled = true; 39 | } 40 | 41 | @Override 42 | public void onCreate(SQLiteDatabase sqLiteDatabase) { 43 | 44 | } 45 | 46 | @Override 47 | public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/SQLiteOpenHelperEnableWriteAheadLogAfterGetDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.content.Context; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.sqlcipher.database.SQLiteOpenHelper; 7 | import net.zetetic.ZeteticApplication; 8 | 9 | import java.io.File; 10 | import java.util.UUID; 11 | 12 | public class SQLiteOpenHelperEnableWriteAheadLogAfterGetDatabaseTest extends SQLCipherTest { 13 | @Override 14 | public boolean execute(SQLiteDatabase database) { 15 | 16 | database.close(); 17 | UUID name = UUID.randomUUID(); 18 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(name.toString()); 19 | DatabaseHelper helper = new DatabaseHelper(ZeteticApplication.getInstance(), 20 | databasePath.getAbsolutePath()); 21 | database = helper.getWritableDatabase("foo"); 22 | helper.setWriteAheadLoggingEnabled(true); 23 | return database.isWriteAheadLoggingEnabled(); 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return "SQLiteOpenHelper Enable WAL After Get DB"; 29 | } 30 | 31 | class DatabaseHelper extends SQLiteOpenHelper { 32 | 33 | public DatabaseHelper(Context context, String databasePath) { 34 | super(context, ZeteticApplication.DATABASE_NAME, null, 1); 35 | } 36 | 37 | @Override 38 | public void onCreate(SQLiteDatabase database) { } 39 | 40 | @Override 41 | public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion){} 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/SQLiteOpenHelperEnableWriteAheadLogBeforeGetDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.content.Context; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.sqlcipher.database.SQLiteOpenHelper; 7 | import net.zetetic.ZeteticApplication; 8 | 9 | import java.io.File; 10 | import java.util.UUID; 11 | 12 | public class SQLiteOpenHelperEnableWriteAheadLogBeforeGetDatabaseTest extends SQLCipherTest { 13 | @Override 14 | public boolean execute(SQLiteDatabase database) { 15 | 16 | database.close(); 17 | UUID name = UUID.randomUUID(); 18 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(name.toString()); 19 | DatabaseHelper helper = new DatabaseHelper(ZeteticApplication.getInstance(), 20 | databasePath.getAbsolutePath()); 21 | helper.setWriteAheadLoggingEnabled(true); 22 | database = helper.getWritableDatabase("foo"); 23 | return database.isWriteAheadLoggingEnabled(); 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return "SQLiteOpenHelper Enable WAL Before Get DB"; 29 | } 30 | 31 | class DatabaseHelper extends SQLiteOpenHelper { 32 | 33 | public DatabaseHelper(Context context, String databasePath) { 34 | super(context, ZeteticApplication.DATABASE_NAME, null, 1); 35 | } 36 | 37 | @Override 38 | public void onCreate(SQLiteDatabase database) { } 39 | 40 | @Override 41 | public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion){} 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/SQLiteOpenHelperGetNameTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.content.Context; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.sqlcipher.database.SQLiteOpenHelper; 7 | import net.zetetic.ZeteticApplication; 8 | 9 | import java.io.File; 10 | import java.util.UUID; 11 | 12 | public class SQLiteOpenHelperGetNameTest extends SQLCipherTest { 13 | @Override 14 | public boolean execute(SQLiteDatabase database) { 15 | UUID name = UUID.randomUUID(); 16 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(name.toString()); 17 | DatabaseHelper helper = new DatabaseHelper(ZeteticApplication.getInstance(), 18 | databasePath.getAbsolutePath()); 19 | return databasePath.getAbsolutePath().equals(helper.getDatabaseName()); 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return "SQLiteOpenHelper GetName Test"; 25 | } 26 | 27 | class DatabaseHelper extends SQLiteOpenHelper { 28 | 29 | public DatabaseHelper(Context context, String databasePath) { 30 | super(context, databasePath, null, 1); 31 | } 32 | 33 | @Override 34 | public void onCreate(SQLiteDatabase database) { } 35 | 36 | @Override 37 | public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion){} 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/SQLiteOpenHelperOnDowngradeTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.content.Context; 4 | 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.sqlcipher.database.SQLiteOpenHelper; 7 | import net.zetetic.ZeteticApplication; 8 | 9 | import java.io.File; 10 | import java.util.UUID; 11 | 12 | public class SQLiteOpenHelperOnDowngradeTest extends SQLCipherTest { 13 | 14 | @Override 15 | public boolean execute(SQLiteDatabase database) { 16 | 17 | UUID name = UUID.randomUUID(); 18 | String password = "foo"; 19 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(name.toString()); 20 | DatabaseHelper helper = new DatabaseHelper(ZeteticApplication.getInstance(), 21 | databasePath.getAbsolutePath(), 2); 22 | helper.getWritableDatabase(password); 23 | if(helper.onDowngradeCalled) return false; 24 | helper.close(); 25 | helper = new DatabaseHelper(ZeteticApplication.getInstance(), databasePath.getAbsolutePath(), 1); 26 | helper.getWritableDatabase(password); 27 | return helper.onDowngradeCalled; 28 | } 29 | 30 | @Override 31 | public String getName() { 32 | return "SQLiteOpenHelper OnDowngrade Test"; 33 | } 34 | 35 | class DatabaseHelper extends SQLiteOpenHelper { 36 | 37 | public boolean onDowngradeCalled = false; 38 | 39 | public DatabaseHelper(Context context, String databasePath, int version) { 40 | super(context, ZeteticApplication.DATABASE_NAME, null, version); 41 | } 42 | 43 | @Override 44 | public void onCreate(SQLiteDatabase database) { } 45 | 46 | @Override 47 | public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion){} 48 | 49 | public void onDowngrade(SQLiteDatabase database, int oldVersion, int newVersion){ 50 | onDowngradeCalled = true; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/SimpleQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.sqlcipher.database.SQLiteStatement; 6 | 7 | import java.util.UUID; 8 | 9 | public class SimpleQueryTest extends SQLCipherTest { 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | database.execSQL("create table t1(a,b);"); 13 | database.execSQL("insert into t1(a, b) values(?, ?);", 14 | new Object[]{UUID.randomUUID().toString(), "foo"}); 15 | database.execSQL("insert into t1(a, b) values(?, ?);", 16 | new Object[]{UUID.randomUUID().toString(), "bar"}); 17 | int count = 0; 18 | Cursor cursor = database.rawQuery("select * from t1 where a = ?1 or ?1 = -1;", 19 | new Object[]{-1}); 20 | if(cursor != null){ 21 | while (cursor.moveToNext()){ 22 | count++; 23 | } 24 | cursor.close(); 25 | } 26 | 27 | // Works 28 | // SQLiteStatement statement = database.compileStatement("select count(*) from t1 where a = ?1 or ?1 = -1;"); 29 | // statement. 30 | // statement.bindLong(1, -1); 31 | // long count = statement.simpleQueryForLong(); 32 | // statement.close(); 33 | return count == 2; 34 | } 35 | 36 | @Override 37 | public String getName() { 38 | return "Simple Query Test"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/SoundexTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | public class SoundexTest extends SQLCipherTest { 7 | 8 | String SQLCIPHER_SOUNDEX = "S421"; 9 | 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | String soundex = QueryHelper.singleValueFromQuery(database, "SELECT soundex('sqlcipher');"); 13 | return SQLCIPHER_SOUNDEX.equals(soundex); 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "Soundex Test"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/StatusMemoryUsedTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class StatusMemoryUsedTest extends SQLCipherTest { 6 | 7 | public static final int SQLITE_STATUS_MEMORY_USED = 0; 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | 12 | int originalMemory = database.status(SQLITE_STATUS_MEMORY_USED, false); 13 | database.execSQL("create table t1(a,b)"); 14 | database.execSQL("insert into t1(a,b) values(?, ?)", 15 | new Object[]{"one for the money", "two for the show"}); 16 | int currentMemory = database.status(SQLITE_STATUS_MEMORY_USED, false); 17 | return originalMemory != currentMemory; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return "Status Memory Used Test"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/TestResult.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | public class TestResult { 4 | 5 | private String name; 6 | private boolean success; 7 | private String message; 8 | private String error; 9 | 10 | public TestResult(String name, boolean success){ 11 | this(name, success, ""); 12 | } 13 | 14 | public TestResult(String name, boolean success, String error){ 15 | this.name = name; 16 | this.success = success; 17 | this.error = error; 18 | } 19 | 20 | public void setResult(boolean success){ 21 | this.success = success; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | public boolean isSuccess() { 29 | return success; 30 | } 31 | 32 | public String getError() {return error;} 33 | 34 | @Override 35 | public String toString() { 36 | return isSuccess() ? "OK" : "FAILED"; 37 | } 38 | 39 | 40 | public void setMessage(String message) { 41 | this.message = message; 42 | } 43 | 44 | public String getMessage(){ 45 | return this.message; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/TextAsDoubleTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class TextAsDoubleTest extends SQLCipherTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.execSQL("create table t1(a TEXT);"); 10 | database.execSQL("insert into t1(a) values(3.14159265359);"); 11 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 12 | if(cursor != null){ 13 | cursor.moveToFirst(); 14 | double value = cursor.getDouble(0); 15 | return value == 3.14159265359; 16 | } 17 | return false; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return "Text As Double Test"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/TextAsIntegerTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class TextAsIntegerTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table t1(a TEXT);"); 11 | database.execSQL("insert into t1(a) values(15);"); 12 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 13 | if(cursor != null){ 14 | cursor.moveToFirst(); 15 | int value = cursor.getInt(0); 16 | return value == 15; 17 | } 18 | return false; 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "Text as Integer Test"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/TextAsLongTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | 6 | public class TextAsLongTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table t1(a TEXT, b TEXT);"); 11 | database.execSQL("insert into t1(a,b) values(500, 500);"); 12 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 13 | if(cursor != null){ 14 | cursor.moveToFirst(); 15 | long value = cursor.getLong(0); 16 | return value == 500; 17 | } 18 | return false; 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "Text as Long Test"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/TransactionNonExclusiveTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class TransactionNonExclusiveTest extends SQLCipherTest { 6 | 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.beginTransactionNonExclusive(); 10 | database.execSQL("create table t1(a,b);"); 11 | database.setTransactionSuccessful(); 12 | database.endTransaction(); 13 | return true; 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "Transaction Immediate Mode"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/TransactionWithListenerTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.sqlcipher.database.SQLiteTransactionListener; 5 | 6 | public class TransactionWithListenerTest extends SQLCipherTest { 7 | 8 | boolean beginCalled = false; 9 | 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | database.beginTransactionWithListener(listener); 13 | database.execSQL("create table t1(a,b);"); 14 | database.setTransactionSuccessful(); 15 | database.endTransaction(); 16 | return beginCalled; 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "Transaction Exclusive Mode"; 22 | } 23 | 24 | SQLiteTransactionListener listener = new SQLiteTransactionListener() { 25 | @Override 26 | public void onBegin() { 27 | beginCalled = true; 28 | } 29 | 30 | @Override 31 | public void onCommit() { 32 | 33 | } 34 | 35 | @Override 36 | public void onRollback() { 37 | 38 | } 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/UnicodeTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.database.Cursor; 4 | import android.util.Log; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.sqlcipher.database.SQLiteStatement; 7 | import java.io.UnsupportedEncodingException; 8 | 9 | public class UnicodeTest extends SQLCipherTest { 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | //if (android.os.Build.VERSION.SDK_INT >= 23) { // Android M 13 | // This will crash on Android releases 1.X-5.X due the following Android bug: 14 | // https://code.google.com/p/android/issues/detail?id=81341 15 | SQLiteStatement st = database.compileStatement("SELECT '\uD83D\uDE03'"); // SMILING FACE (MOUTH OPEN) 16 | String res = st.simpleQueryForString(); 17 | String message = String.format("Returned value:%s", res); 18 | setMessage(message); 19 | Log.i(TAG, message); 20 | return res.equals("\uD83D\uDE03"); 21 | //} 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "Unicode Test"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/VerifyCipherProviderTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | public class VerifyCipherProviderTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | String provider = QueryHelper.singleValueFromQuery(database, 11 | "PRAGMA cipher_provider;"); 12 | setMessage(String.format("Reported:%s", provider)); 13 | return provider.contains("openssl"); 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "Verify Cipher Provider Test"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/VerifyCipherProviderVersionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | 6 | public class VerifyCipherProviderVersionTest extends SQLCipherTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | String provider = QueryHelper.singleValueFromQuery(database, 11 | "PRAGMA cipher_provider_version;"); 12 | setMessage(String.format("Reported:%s", provider)); 13 | return provider.contains("OpenSSL 1.1.1") || 14 | provider.contains("OpenSSL 1.0.2u-fips"); 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return "Verify Cipher Provider Version"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/VerifyOnUpgradeIsCalledTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import android.content.Context; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.sqlcipher.database.SQLiteOpenHelper; 6 | import net.zetetic.ZeteticApplication; 7 | 8 | public class VerifyOnUpgradeIsCalledTest extends SQLCipherTest { 9 | 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | 13 | ZeteticApplication.getInstance().deleteDatabaseFileAndSiblings(ZeteticApplication.DATABASE_NAME); 14 | DatabaseHelper firstRun = new DatabaseHelper(ZeteticApplication.getInstance(), 1); 15 | SQLiteDatabase db = firstRun.getWritableDatabase(ZeteticApplication.DATABASE_PASSWORD); 16 | db.close(); 17 | DatabaseHelper secondRun = new DatabaseHelper(ZeteticApplication.getInstance(), 2); 18 | SQLiteDatabase db2 = secondRun.getWritableDatabase(ZeteticApplication.DATABASE_PASSWORD); 19 | db2.close(); 20 | return secondRun.OnUpgradeCalled; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Verify onUpgrade Is Called Test"; 26 | } 27 | 28 | class DatabaseHelper extends SQLiteOpenHelper { 29 | 30 | public boolean OnUpgradeCalled; 31 | 32 | public DatabaseHelper(Context context, int version) { 33 | super(context, ZeteticApplication.DATABASE_NAME, null, version); 34 | } 35 | 36 | @Override 37 | public void onCreate(SQLiteDatabase database) { 38 | database.execSQL("create table t1(a,b)"); 39 | } 40 | 41 | @Override 42 | public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) { 43 | OnUpgradeCalled = true; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/WriteAheadLoggingWithAttachedDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.ZeteticApplication; 5 | 6 | import java.io.File; 7 | import java.util.UUID; 8 | 9 | public class WriteAheadLoggingWithAttachedDatabaseTest extends SQLCipherTest { 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | UUID name = UUID.randomUUID(); 13 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(name.toString()); 14 | database.execSQL("ATTACH DATABASE ? as foo;", new Object[]{databasePath.getAbsolutePath()}); 15 | boolean result = database.enableWriteAheadLogging(); 16 | return result == false; 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "Disallow WAL Mode with Attached DB"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/WriteAheadLoggingWithInMemoryDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class WriteAheadLoggingWithInMemoryDatabaseTest extends SQLCipherTest { 6 | @Override 7 | public boolean execute(SQLiteDatabase database) { 8 | database.close(); 9 | database = SQLiteDatabase.openDatabase(SQLiteDatabase.MEMORY, "", 10 | null, SQLiteDatabase.OPEN_READWRITE); 11 | boolean result = database.enableWriteAheadLogging(); 12 | return result == false; 13 | } 14 | 15 | @Override 16 | public String getName() { 17 | return "Disallow WAL Mode with in memory DB"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/WriteAheadLoggingWithTransactionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | 5 | public class WriteAheadLoggingWithTransactionTest extends SQLCipherTest { 6 | 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.beginTransaction(); 10 | try { 11 | database.enableWriteAheadLogging(); 12 | } catch (IllegalStateException ex){ 13 | if(ex.getMessage().equals("Write Ahead Logging cannot be enabled while in a transaction")) { 14 | return true; 15 | } 16 | } 17 | return false; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return "Disallow WAL Mode while in transaction"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/AttachDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.ZeteticApplication; 6 | import net.zetetic.tests.SQLCipherTest; 7 | import java.io.File; 8 | 9 | public class AttachDatabaseTest extends SupportTest { 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | boolean status; 13 | String password = "test123"; 14 | File fooDatabase = ZeteticApplication.getInstance().getDatabasePath("foo.db"); 15 | if(fooDatabase.exists()){ 16 | fooDatabase.delete(); 17 | } 18 | database.execSQL("ATTACH database ? AS encrypted KEY ?", new Object[]{fooDatabase.getAbsolutePath(), password}); 19 | database.execSQL("create table encrypted.t1(a,b);"); 20 | database.execSQL("insert into encrypted.t1(a,b) values(?,?);", new Object[]{"one for the money", "two for the show"}); 21 | int rowCount = QueryHelper.singleIntegerValueFromQuery(database, "select count(*) from encrypted.t1;"); 22 | status = rowCount == 1; 23 | database.close(); 24 | return status; 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "Attach database test"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/AttachNewDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.ZeteticApplication; 5 | import net.zetetic.tests.SQLCipherTest; 6 | import java.io.File; 7 | 8 | public class AttachNewDatabaseTest extends SupportTest { 9 | @Override 10 | public boolean execute(SQLiteDatabase encryptedDatabase) { 11 | 12 | encryptedDatabase.execSQL("create table t1(a,b)"); 13 | encryptedDatabase.execSQL("insert into t1(a,b) values(?, ?)", new Object[]{"one", "two"}); 14 | 15 | String newKey = "foo"; 16 | File newDatabasePath = ZeteticApplication.getInstance().getDatabasePath("normal.db"); 17 | String attachCommand = "ATTACH DATABASE ? as encrypted KEY ?"; 18 | String createCommand = "create table encrypted.t1(a,b)"; 19 | String insertCommand = "insert into encrypted.t1 SELECT * from t1"; 20 | String detachCommand = "DETACH DATABASE encrypted"; 21 | encryptedDatabase.execSQL(attachCommand, new Object[]{newDatabasePath.getAbsolutePath(), newKey}); 22 | encryptedDatabase.execSQL(createCommand); 23 | encryptedDatabase.execSQL(insertCommand); 24 | encryptedDatabase.execSQL(detachCommand); 25 | 26 | return true; 27 | } 28 | 29 | @Override 30 | protected void tearDown(SQLiteDatabase database) { 31 | File newDatabasePath = ZeteticApplication.getInstance().getDatabasePath("normal.db"); 32 | newDatabasePath.delete(); 33 | } 34 | 35 | @Override 36 | public String getName() { 37 | return "Attach New Database Test"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/BeginTransactionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.tests.SQLCipherTest; 5 | 6 | public class BeginTransactionTest extends SupportTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.beginTransaction(); 10 | database.endTransaction(); 11 | return true; 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "Begin transaction test"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/BindBooleanRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class BindBooleanRawQueryTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table t1(a,b);"); 11 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", true}); 12 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{true}); 13 | if(cursor != null){ 14 | if(cursor.moveToFirst()) { 15 | String a = cursor.getString(0); 16 | int b = cursor.getInt(1); 17 | cursor.close(); 18 | return a.equals("one for the money") && b == 1; 19 | } 20 | } 21 | return false; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "Bind Boolean for RawQuery Test"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/BindByteArrayRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | import java.security.SecureRandom; 7 | import java.util.Arrays; 8 | 9 | public class BindByteArrayRawQueryTest extends SupportTest { 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | 13 | SecureRandom random = new SecureRandom(); 14 | byte[] randomData = new byte[20]; 15 | random.nextBytes(randomData); 16 | database.execSQL("create table t1(a,b);"); 17 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", randomData}); 18 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{randomData}); 19 | if(cursor != null){ 20 | if(cursor.moveToFirst()) { 21 | String a = cursor.getString(0); 22 | byte[] b = cursor.getBlob(1); 23 | cursor.close(); 24 | return a.equals("one for the money") && Arrays.equals(randomData, b); 25 | } 26 | } 27 | return false; 28 | } 29 | 30 | @Override 31 | public String getName() { 32 | return "Bind Byte Array for RawQuery Test"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/BindDoubleRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class BindDoubleRawQueryTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table t1(a,b);"); 11 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", 2.0d}); 12 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{2.0d}); 13 | if(cursor != null){ 14 | if(cursor.moveToFirst()) { 15 | String a = cursor.getString(0); 16 | Double b = cursor.getDouble(1); 17 | cursor.close(); 18 | return a.equals("one for the money") && b == 2.0d; 19 | } 20 | } 21 | return false; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "Bind Double for RawQuery Test"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/BindFloatRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class BindFloatRawQueryTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table t1(a,b);"); 11 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", 2.25f}); 12 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{2.25f}); 13 | if(cursor != null){ 14 | if(cursor.moveToFirst()) { 15 | String a = cursor.getString(0); 16 | float b = cursor.getFloat(1); 17 | cursor.close(); 18 | return a.equals("one for the money") && b == 2.25f; 19 | } 20 | } 21 | return false; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "Bind Float for RawQuery Test"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/BindLongRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class BindLongRawQueryTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table t1(a,b);"); 11 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", 2L}); 12 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{2L}); 13 | if(cursor != null){ 14 | if(cursor.moveToFirst()) { 15 | String a = cursor.getString(0); 16 | long b = cursor.getLong(1); 17 | cursor.close(); 18 | return a.equals("one for the money") && b == 2L; 19 | } 20 | } 21 | return false; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "Bind Long for RawQuery Test"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/BindStringRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class BindStringRawQueryTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table t1(a,b);"); 11 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", "two for the show"}); 12 | Cursor cursor = database.rawQuery("select * from t1 where b = ?;", new Object[]{"two for the show"}); 13 | if(cursor != null){ 14 | if(cursor.moveToFirst()) { 15 | String a = cursor.getString(0); 16 | String b = cursor.getString(1); 17 | cursor.close(); 18 | return a.equals("one for the money") && b.equals("two for the show"); 19 | } 20 | } 21 | return false; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "Bind String for RawQuery Test"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CanThrowSQLiteExceptionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import android.database.sqlite.SQLiteException; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class CanThrowSQLiteExceptionTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | 12 | try{ 13 | throw new SQLiteException(); 14 | }catch (SQLiteException ex){ 15 | return true; 16 | } 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "SQLiteException Test"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CheckIsDatabaseIntegrityOkTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.tests.SQLCipherTest; 5 | 6 | public class CheckIsDatabaseIntegrityOkTest extends SupportTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | return database.isDatabaseIntegrityOk(); 10 | } 11 | 12 | @Override 13 | public String getName() { 14 | return "Check Database Integrity"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CheckIsWriteAheadLoggingEnabledTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.tests.SQLCipherTest; 5 | 6 | public class CheckIsWriteAheadLoggingEnabledTest extends SupportTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.enableWriteAheadLogging(); 10 | boolean statusWhenEnabled = database.isWriteAheadLoggingEnabled(); 11 | database.disableWriteAheadLogging(); 12 | boolean statusWhenDisabled = database.isWriteAheadLoggingEnabled(); 13 | return statusWhenEnabled && !statusWhenDisabled; 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "Test isWriteAheadLoggingEnabled"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CompileBeginTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.tests.SQLCipherTest; 5 | 6 | public class CompileBeginTest extends SupportTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | try { 11 | database.compileStatement("begin").execute(); 12 | return true; 13 | }catch (Exception e){ 14 | return false; 15 | } 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return "Compile Begin Test"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CompileStatementSyntaxErrorMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.util.Log; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteException; 6 | import net.sqlcipher.database.SQLiteStatement; 7 | import net.zetetic.ZeteticApplication; 8 | import net.zetetic.tests.SQLCipherTest; 9 | 10 | public class CompileStatementSyntaxErrorMessageTest extends SupportTest { 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | try { 15 | SQLiteStatement ignored = database.compileStatement("INSERT INTO mytable (mydata) VALUES"); 16 | } catch (SQLiteException e) { 17 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteException", e); 18 | String message = e.getMessage(); 19 | setMessage(message); 20 | // TBD missing error code etc. 21 | if (!message.matches("incomplete input: , while compiling: INSERT INTO mytable \\(mydata\\) VALUES")) { 22 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 23 | return false; 24 | } 25 | return true; 26 | } catch (Exception e) { 27 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 28 | return false; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | @Override 35 | public String getName() { 36 | return "Compile statement syntax error message Test"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CompiledSQLUpdateTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.sqlcipher.database.SQLiteStatement; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class CompiledSQLUpdateTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | 11 | database.rawExecSQL("create table ut1(a text, b integer)"); 12 | database.execSQL("insert into ut1(a, b) values (?,?)", new Object[]{"s1", new Integer(100)}); 13 | 14 | SQLiteStatement st = database.compileStatement("update ut1 set b = 101 where b = 100"); 15 | long recs = st.executeUpdateDelete(); 16 | return (recs == 1); 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "Compiled SQL update test"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/ComputeKDFTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class ComputeKDFTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | database.rawExecSQL("PRAGMA cipher_kdf_compute;"); 12 | String kdf = QueryHelper.singleValueFromQuery(database, "PRAGMA kdf_iter;"); 13 | setMessage(String.format("Computed KDF:%s", kdf)); 14 | return true; 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return "Compute KDF Test"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CopyStringToBufferNullTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.zetetic.tests.SQLCipherTest; 7 | 8 | public class CopyStringToBufferNullTest extends SupportTest { 9 | 10 | private CharArrayBuffer charArrayBuffer = null; 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | boolean result = false; 15 | try { 16 | database.execSQL("create table t1(a TEXT, b TEXT);"); 17 | database.execSQL("insert into t1(a,b) values(500, 500);"); 18 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 19 | if(cursor != null){ 20 | cursor.moveToFirst(); 21 | cursor.copyStringToBuffer(0, charArrayBuffer); 22 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 23 | "500".equals(actualValue); 24 | } 25 | } catch (IllegalArgumentException ex){ 26 | result = true; 27 | } finally { 28 | return result; 29 | } 30 | 31 | } 32 | 33 | @Override 34 | public String getName() { 35 | return "Copy String To Buffer Null Test"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CopyStringToBufferTestFloatLargeBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.zetetic.tests.SQLCipherTest; 7 | 8 | public class CopyStringToBufferTestFloatLargeBuffer extends SupportTest { 9 | 10 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(128); 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | 15 | database.execSQL("create table t1(a REAL, b REAL);"); 16 | database.execSQL("insert into t1(a,b) values(123.45, 67.89);"); 17 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 18 | if(cursor != null){ 19 | cursor.moveToFirst(); 20 | cursor.copyStringToBuffer(1, charArrayBuffer); 21 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 22 | return "67.89".equals(actualValue); 23 | } 24 | return false; 25 | 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "Copy String To Buffer Test Float Large Buffer"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CopyStringToBufferTestFloatSmallBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.zetetic.tests.SQLCipherTest; 7 | 8 | public class CopyStringToBufferTestFloatSmallBuffer extends SupportTest { 9 | 10 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(1); 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | 15 | database.execSQL("create table t1(a REAL, b REAL);"); 16 | database.execSQL("insert into t1(a,b) values(123.45, 67.89);"); 17 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 18 | if(cursor != null){ 19 | cursor.moveToFirst(); 20 | cursor.copyStringToBuffer(1, charArrayBuffer); 21 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 22 | return "67.89".equals(actualValue); 23 | } 24 | return false; 25 | 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "Copy String To Buffer Test Float Small Buffer"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CopyStringToBufferTestIntegerLargeBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.zetetic.tests.SQLCipherTest; 7 | 8 | public class CopyStringToBufferTestIntegerLargeBuffer extends SupportTest { 9 | 10 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(128); 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | 15 | database.execSQL("create table t1(a INTEGER, b INTEGER);"); 16 | database.execSQL("insert into t1(a,b) values(123, 456);"); 17 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 18 | if(cursor != null){ 19 | cursor.moveToFirst(); 20 | cursor.copyStringToBuffer(1, charArrayBuffer); 21 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 22 | return "456".equals(actualValue); 23 | } 24 | return false; 25 | 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "Copy String To Buffer Test Integer Large Buffer"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CopyStringToBufferTestIntegerSmallBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.zetetic.tests.SQLCipherTest; 7 | 8 | public class CopyStringToBufferTestIntegerSmallBuffer extends SupportTest { 9 | 10 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(1); 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | 15 | database.execSQL("create table t1(a INTEGER, b INTEGER);"); 16 | database.execSQL("insert into t1(a,b) values(123, 456);"); 17 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 18 | if(cursor != null){ 19 | cursor.moveToFirst(); 20 | cursor.copyStringToBuffer(1, charArrayBuffer); 21 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 22 | return "456".equals(actualValue); 23 | } 24 | return false; 25 | 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "Copy String To Buffer Test Integer Small Buffer"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CopyStringToBufferTestStringLargeBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.zetetic.tests.SQLCipherTest; 7 | 8 | public class CopyStringToBufferTestStringLargeBuffer extends SupportTest { 9 | 10 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(128); 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | database.execSQL("create table t1(a TEXT, b TEXT);"); 15 | database.execSQL("insert into t1(a,b) values(500, 500);"); 16 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 17 | if(cursor != null){ 18 | cursor.moveToFirst(); 19 | cursor.copyStringToBuffer(0, charArrayBuffer); 20 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 21 | return "500".equals(actualValue); 22 | } 23 | return false; 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return "Copy String To Buffer Test String Large Buffer"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CopyStringToBufferTestStringSmallBuffer.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.CharArrayBuffer; 4 | import net.sqlcipher.Cursor; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.zetetic.tests.SQLCipherTest; 7 | 8 | public class CopyStringToBufferTestStringSmallBuffer extends SupportTest { 9 | 10 | private CharArrayBuffer charArrayBuffer = new CharArrayBuffer(1); 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | database.execSQL("create table t1(a TEXT, b TEXT);"); 15 | database.execSQL("insert into t1(a,b) values(500, 500);"); 16 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 17 | if(cursor != null){ 18 | cursor.moveToFirst(); 19 | cursor.copyStringToBuffer(0, charArrayBuffer); 20 | String actualValue = new String(charArrayBuffer.data, 0, charArrayBuffer.sizeCopied); 21 | return "500".equals(actualValue); 22 | } 23 | return false; 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return "Copy String To Buffer Test String Small Buffer"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/CreateOpenDatabaseWithByteArrayTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.ZeteticApplication; 6 | import net.zetetic.tests.SQLCipherTest; 7 | import java.io.File; 8 | 9 | public class CreateOpenDatabaseWithByteArrayTest extends SupportTest { 10 | 11 | private String databaseName = "foo.db"; 12 | 13 | @Override 14 | public boolean execute(SQLiteDatabase database) { 15 | boolean status = false; 16 | database.close(); 17 | byte[] key = generateRandomByteArray(32); 18 | File newDatabasePath = ZeteticApplication.getInstance().getDatabasePath(databaseName); 19 | newDatabasePath.delete(); 20 | database = SQLiteDatabase.openOrCreateDatabase(newDatabasePath.getPath(), key, null); 21 | database.execSQL("create table t1(a,b);"); 22 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{1, 2}); 23 | database.close(); 24 | database = SQLiteDatabase.openOrCreateDatabase(newDatabasePath.getPath(), key, null); 25 | Cursor cursor = database.rawQuery("select * from t1;", null); 26 | if (cursor != null) { 27 | cursor.moveToNext(); 28 | int a = cursor.getInt(0); 29 | int b = cursor.getInt(1); 30 | cursor.close(); 31 | status = a == 1 && b == 2; 32 | } 33 | return status; 34 | } 35 | 36 | @Override 37 | public String getName() { 38 | return "Create/Open with Byte Array Test"; 39 | } 40 | 41 | @Override 42 | protected void tearDown(SQLiteDatabase database) { 43 | super.tearDown(database); 44 | File newDatabasePath = ZeteticApplication.getInstance().getDatabasePath(databaseName); 45 | newDatabasePath.delete(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/DisableWriteAheadLoggingTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class DisableWriteAheadLoggingTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | boolean result = database.enableWriteAheadLogging(); 11 | String currentMode = getJournalModeState(database); 12 | if(!result || !currentMode.equals("wal")) return false; 13 | database.disableWriteAheadLogging(); 14 | currentMode = getJournalModeState(database); 15 | return currentMode.equals("delete"); 16 | } 17 | 18 | private String getJournalModeState(SQLiteDatabase database){ 19 | return QueryHelper.singleValueFromQuery(database, "PRAGMA journal_mode;"); 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return "Disable WAL mode"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/EnableForeignKeyConstraintsTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class EnableForeignKeyConstraintsTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | String initialState = getForeignKeyState(database); 11 | if(!initialState.equals("0")) return false; 12 | database.setForeignKeyConstraintsEnabled(true); 13 | String currentState = getForeignKeyState(database); 14 | if(!currentState.equals("1")) return false; 15 | return true; 16 | } 17 | 18 | private String getForeignKeyState(SQLiteDatabase database){ 19 | return QueryHelper.singleValueFromQuery(database, "PRAGMA foreign_keys"); 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return "Enable Foreign Key Constraints"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/EnableForeignKeySupportTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class EnableForeignKeySupportTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | String defaultValue = QueryHelper.singleValueFromQuery(database, "PRAGMA foreign_keys"); 11 | database.rawExecSQL("PRAGMA foreign_keys = ON;"); 12 | String updatedValue = QueryHelper.singleValueFromQuery(database, "PRAGMA foreign_keys"); 13 | return defaultValue.equals("0") && updatedValue.equals("1"); 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "Enable Foreign Key Support Test"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/EnableWriteAheadLoggingTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class EnableWriteAheadLoggingTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | boolean result = database.enableWriteAheadLogging(); 11 | String currentMode = QueryHelper.singleValueFromQuery(database, "PRAGMA journal_mode;"); 12 | return result && currentMode.equals("wal"); 13 | } 14 | 15 | @Override 16 | public String getName() { 17 | return "Enable WAL mode"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/ExecuteInsertConstraintErrorMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.util.Log; 4 | import android.database.sqlite.SQLiteConstraintException; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.sqlcipher.database.SQLiteStatement; 7 | import net.zetetic.ZeteticApplication; 8 | import net.zetetic.tests.SQLCipherTest; 9 | 10 | public class ExecuteInsertConstraintErrorMessageTest extends SupportTest { 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | database.execSQL("CREATE TABLE tt(a UNIQUE, b)"); 15 | database.execSQL("INSERT INTO tt VALUES (101, 'Alice')"); 16 | try { 17 | SQLiteStatement insertStatement = database.compileStatement("INSERT INTO tt VALUES (101, 'Betty')"); 18 | long ignored = insertStatement.executeInsert(); 19 | } catch (SQLiteConstraintException e) { 20 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteConstraintException", e); 21 | String message = e.getMessage(); 22 | setMessage(message); 23 | if (!message.matches("error code 19 \\(extended error code 2067\\): UNIQUE constraint failed: tt\\.a")) { 24 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 25 | return false; 26 | } 27 | return true; 28 | } catch (Exception e) { 29 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 30 | return false; 31 | } 32 | 33 | return false; 34 | } 35 | 36 | @Override 37 | public String getName() { 38 | return "Execute insert constraint error message Test"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/FIPSTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class FIPSTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | 11 | String version = QueryHelper.singleValueFromQuery(database, "PRAGMA cipher_version;"); 12 | setMessage(String.format("SQLCipher version:%s", version)); 13 | int expectedValue = version.contains("FIPS") ? 1 : 0; 14 | 15 | int status = QueryHelper.singleIntegerValueFromQuery(database, "PRAGMA cipher_fips_status;"); 16 | return status == expectedValue; 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "FIPS Test"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/FTS5Test.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class FTS5Test extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("CREATE VIRTUAL TABLE email USING fts5(sender, title, body);"); 11 | database.execSQL("insert into email(sender, title, body) values(?, ?, ?);", 12 | new Object[]{"foo@bar.com", "Test Email", "This is a test email message."}); 13 | Cursor cursor = database.rawQuery("select * from email where email match ?;", new String[]{"test"}); 14 | if(cursor != null){ 15 | cursor.moveToFirst(); 16 | return cursor.getString(cursor.getColumnIndex("sender")).equals("foo@bar.com"); 17 | } 18 | return false; 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "FTS5 Test"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/FixedCursorWindowAllocationTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.CursorWindow; 5 | import net.sqlcipher.CursorWindowAllocation; 6 | import net.sqlcipher.CustomCursorWindowAllocation; 7 | import net.sqlcipher.database.SQLiteDatabase; 8 | import net.zetetic.tests.RowColumnValueBuilder; 9 | import net.zetetic.tests.SQLCipherTest; 10 | 11 | public class FixedCursorWindowAllocationTest extends SupportTest { 12 | 13 | @Override 14 | public boolean execute(SQLiteDatabase database) { 15 | try { 16 | int rowCount = 0; 17 | int rows = 100; 18 | long allocationSize = 1024; 19 | final int dataSize = 491; 20 | CursorWindowAllocation fixedAllocation = new CustomCursorWindowAllocation(allocationSize, 0, allocationSize); 21 | CursorWindow.setCursorWindowAllocation(fixedAllocation); 22 | buildDatabase(database, rows, 1, new RowColumnValueBuilder() { 23 | @Override 24 | public Object buildRowColumnValue(String[] columns, int row, int column) { 25 | return generateRandomByteArray(dataSize); 26 | } 27 | }); 28 | 29 | Cursor cursor = database.rawQuery("SELECT * FROM t1;", new Object[]{}); 30 | if(cursor == null) return false; 31 | while(cursor.moveToNext()){ 32 | byte[] data = cursor.getBlob(0); 33 | if(data.length != dataSize) { 34 | cursor.close(); 35 | return false; 36 | } 37 | rowCount++; 38 | } 39 | cursor.close(); 40 | return rowCount == rows; 41 | } catch (Exception e){ 42 | String message = String.format("Error:%s", e.getMessage()); 43 | log(message); 44 | setMessage(message); 45 | return false; 46 | } 47 | } 48 | 49 | @Override 50 | public String getName() { 51 | return "Small Cursor Window Allocation Test"; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/ForeignKeyConstraintsEnabledWithTransactionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.tests.SQLCipherTest; 5 | 6 | public class ForeignKeyConstraintsEnabledWithTransactionTest extends SupportTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | database.beginTransaction(); 10 | try { 11 | database.setForeignKeyConstraintsEnabled(true); 12 | }catch (IllegalStateException ex){ 13 | if(ex.getMessage().equals("Foreign key constraints may not be changed while in a transaction")) { 14 | return true; 15 | } 16 | } 17 | return false; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return "Disallow foreign key constraints in transaction"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/FullTextSearchTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class FullTextSearchTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | 12 | database.execSQL("CREATE VIRTUAL TABLE sites USING fts4(domain, url, title, meta_keys, body)"); 13 | database.execSQL("CREATE TABLE keywords (keyword TEXT)"); 14 | 15 | database.execSQL("insert into sites(domain, url, title, meta_keys, body) values(?, ?, ?, ?, ?)", 16 | new Object[]{"sqlcipher.net", "http://sqlcipher.net", 17 | "Home - SQLCipher - Open Source Full Database Encryption for SQLite", 18 | "sqlcipher, sqlite", ""}); 19 | database.execSQL("insert into keywords(keyword) values(?)", new Object[]{"SQLCipher"}); 20 | database.execSQL("insert into keywords(keyword) values(?)", new Object[]{"SQLite"}); 21 | 22 | String query = "SELECT keyword FROM keywords INNER JOIN sites ON sites.title MATCH keywords.keyword"; 23 | Cursor result = database.rawQuery(query, new String[]{}); 24 | int resultCount = 0; 25 | while (result.moveToNext()){ 26 | String row = result.getString(0); 27 | if(row != null){ 28 | resultCount++; 29 | } 30 | } 31 | result.close(); 32 | return resultCount > 0; 33 | } 34 | 35 | @Override 36 | public String getName() { 37 | return "Full Text Search Test"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/GetAttachedDatabasesTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.util.Pair; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.ZeteticApplication; 6 | import net.zetetic.tests.SQLCipherTest; 7 | import java.io.File; 8 | import java.util.List; 9 | import java.util.UUID; 10 | 11 | public class GetAttachedDatabasesTest extends SupportTest { 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | UUID id = UUID.randomUUID(); 15 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(id.toString()); 16 | List> attached = database.getAttachedDbs(); 17 | boolean initialAttach = attached.size() == 1 && attached.get(0).first.equals("main"); 18 | database.execSQL("ATTACH database ? as foo;", 19 | new Object[]{databasePath.getAbsolutePath()}); 20 | attached = database.getAttachedDbs(); 21 | return initialAttach && attached.size() == 2; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "Get Attached Databases Test"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/GetTypeFromCrossProcessCursorWrapperTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class GetTypeFromCrossProcessCursorWrapperTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | database.execSQL("create table t1(a,b);"); 12 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", "two for the show"}); 13 | Cursor cursor = database.query("t1", new String[]{"a", "b"}, null, null, null, null, null); 14 | cursor.moveToFirst(); 15 | int type_a = cursor.getType(0); 16 | int type_b = cursor.getType(1); 17 | cursor.close(); 18 | database.close(); 19 | return (type_a == Cursor.FIELD_TYPE_STRING) && (type_b == Cursor.FIELD_TYPE_STRING); 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return "Get Type from CrossProcessCursorWrapper"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/ISupportTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.zetetic.tests.TestResult; 4 | 5 | interface ISupportTest { 6 | String getName(); 7 | TestResult run(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/InsertWithOnConflictTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.content.ContentValues; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class InsertWithOnConflictTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table user(_id integer primary key autoincrement, email text unique not null);"); 11 | ContentValues values = new ContentValues(); 12 | values.put("email", "foo@bar.com"); 13 | long id = database.insertWithOnConflict("user", null, values, 14 | SQLiteDatabase.CONFLICT_IGNORE); 15 | long error = database.insertWithOnConflict("user", null, values, 16 | SQLiteDatabase.CONFLICT_IGNORE); 17 | return id == 1 && error == -1; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return "Insert with OnConflict"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/JavaClientLibraryVersionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.tests.SQLCipherTest; 5 | 6 | public class JavaClientLibraryVersionTest extends SupportTest { 7 | 8 | private final String EXPECTED_SQLCIPHER_ANDROID_VERSION = "4.5.4"; 9 | 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | setMessage(String.format("Report:%s", SQLiteDatabase.SQLCIPHER_ANDROID_VERSION)); 13 | return SQLiteDatabase.SQLCIPHER_ANDROID_VERSION.equals(EXPECTED_SQLCIPHER_ANDROID_VERSION); 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return "Java Client Library Version Test"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/LoopingCountQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class LoopingCountQueryTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | int counter = 0; 12 | int iterations = 10; 13 | database.execSQL("create table t1(a);"); 14 | database.execSQL("insert into t1(a) values (?)", new Object[]{"foo"}); 15 | StringBuilder buffer = new StringBuilder(); 16 | while(counter < iterations){ 17 | Cursor cursor = database.rawQuery("select count(*) from t1", null); 18 | if(cursor != null){ 19 | cursor.moveToFirst(); 20 | buffer.append(cursor.getInt(0)); 21 | cursor.close(); 22 | } 23 | counter++; 24 | } 25 | return buffer.toString().length() > 0; 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "Looping Count Query Test"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/LoopingInsertTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.util.Log; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class LoopingInsertTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("CREATE TABLE some_table(name TEXT, surname TEXT);"); 11 | long startTime = System.currentTimeMillis(); 12 | database.execSQL("begin;"); 13 | for(int index = 0; index < 10000; index++){ 14 | database.execSQL("insert into some_table(name, surname) values(?, ?)", 15 | new Object[]{"one for the money", "two for the show"}); 16 | } 17 | database.execSQL("commit;"); 18 | long diff = System.currentTimeMillis() - startTime; 19 | Log.e(TAG, String.format("Inserted in: %d ms", diff)); 20 | return true; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Looping Insert Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/LoopingQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class LoopingQueryTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | int counter = 0; 12 | int iterations = 1000; 13 | database.execSQL("create table t1(a);"); 14 | database.execSQL("insert into t1(a) values (?)", new Object[]{"foo"}); 15 | StringBuilder buffer = new StringBuilder(); 16 | while(counter < iterations){ 17 | Cursor cursor = database.rawQuery("select * from t1", null); 18 | if(cursor != null){ 19 | cursor.moveToFirst(); 20 | buffer.append(cursor.getString(0)); 21 | cursor.close(); 22 | } 23 | counter++; 24 | } 25 | return buffer.toString().length() > 0; 26 | } 27 | 28 | @Override 29 | public String getName() { 30 | return "Looping Query Test"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/NestedTransactionsTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | 8 | public class NestedTransactionsTest extends SupportTest { 9 | 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | database.rawExecSQL("savepoint foo;"); 13 | database.rawExecSQL("create table t1(a,b);"); 14 | database.execSQL("insert into t1(a,b) values(?,?);", new Object[]{"one for the money", "two for the show"}); 15 | database.rawExecSQL("savepoint bar;"); 16 | database.execSQL("insert into t1(a,b) values(?,?);", new Object[]{"three to get ready", "go man go"}); 17 | database.rawExecSQL("rollback transaction to bar;"); 18 | database.rawExecSQL("commit;"); 19 | int count = QueryHelper.singleIntegerValueFromQuery(database, "select count(*) from t1;"); 20 | return count == 1; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Nested Transactions Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/NullQueryResultTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class NullQueryResultTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | 12 | database.execSQL("create table t1(a,b);"); 13 | database.execSQL("insert into t1(a,b) values (?, ?)", new Object[]{"foo", null}); 14 | database.execSQL("insert into t1(a,b) values (?, ?)", new Object[]{"bar", null}); 15 | Cursor cursor = database.rawQuery("select a from t1", null); 16 | StringBuilder buffer = new StringBuilder(); 17 | while(cursor.moveToNext()){ 18 | buffer.append(cursor.getString(0)); 19 | } 20 | cursor.close(); 21 | return buffer.toString().length() > 0; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "Null Query Test"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/NullRawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class NullRawQueryTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table t1(a,b);"); 11 | database.execSQL("insert into t1(a,b) values(?, ?);", new Object[]{"one for the money", "two for the show"}); 12 | Cursor cursor = database.rawQuery("select * from t1;", null); 13 | if(cursor != null){ 14 | if(cursor.moveToFirst()) { 15 | String a = cursor.getString(0); 16 | String b = cursor.getString(1); 17 | cursor.close(); 18 | return a.equals("one for the money") && b.equals("two for the show"); 19 | } 20 | } 21 | 22 | 23 | return false; 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return "Bind Null Raw Query Test"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/PragmaCipherVersionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.Cursor; 4 | import android.util.Log; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import net.zetetic.tests.SQLCipherTest; 7 | 8 | public class PragmaCipherVersionTest extends SupportTest { 9 | 10 | private final String CURRENT_CIPHER_VERSION = "4.5.4"; 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | 15 | Log.i(TAG, "Before rawQuery"); 16 | Cursor cursor = database.rawQuery("PRAGMA cipher_version", new String[]{}); 17 | Log.i(TAG, "After rawQuery"); 18 | if(cursor != null){ 19 | Log.i(TAG, "Before cursor.moveToNext()"); 20 | cursor.moveToNext(); 21 | Log.i(TAG, "Before cursor.getString(0)"); 22 | String cipherVersion = cursor.getString(0); 23 | Log.i(TAG, "Before cursor.close"); 24 | cursor.close(); 25 | setMessage(String.format("Reported:%s", cipherVersion)); 26 | return cipherVersion.contains(CURRENT_CIPHER_VERSION); 27 | } 28 | return false; 29 | } 30 | 31 | @Override 32 | public String getName() { 33 | return "PRAGMA cipher_version Test"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/QueryDataSizeTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.sqlcipher.database.SQLiteQueryStats; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class QueryDataSizeTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("CREATE TABLE t1(a,b);"); 11 | database.execSQL("INSERT INTO t1(a,b) VALUES(?, ?);", 12 | new Object[]{generateRandomByteArray(256), generateRandomByteArray(256)}); 13 | database.execSQL("INSERT INTO t1(a,b) VALUES(?, ?);", 14 | new Object[]{generateRandomByteArray(1024), generateRandomByteArray(64)}); 15 | SQLiteQueryStats result = database.getQueryStats("SELECT * FROM t1;", new Object[]{}); 16 | return result.getTotalQueryResultSize() > 0 && result.getLargestIndividualRowSize() > 0; 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "Query Data Size Test"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/QueryFloatToStringTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class QueryFloatToStringTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | String value = QueryHelper.singleValueFromQuery(database, "SELECT 42.09;"); 11 | return value.equals("42.09"); 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "Query Float to String"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/QueryIntegerToStringTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class QueryIntegerToStringTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | String value = QueryHelper.singleValueFromQuery(database, "SELECT 123;"); 11 | return value.equals("123"); 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return "Query Integer to String"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/RTreeTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class RTreeTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | int id = 0; 11 | String create = "CREATE VIRTUAL TABLE demo_index USING rtree(id, minX, maxX, minY, maxY);"; 12 | String insert = "INSERT INTO demo_index VALUES(?, ?, ?, ?, ?);"; 13 | database.execSQL(create); 14 | database.execSQL(insert, new Object[]{1, -80.7749, -80.7747, 35.3776, 35.3778}); 15 | Cursor cursor = database.rawQuery("SELECT * FROM demo_index WHERE maxY < ?;", 16 | new Object[]{36}); 17 | if(cursor != null){ 18 | cursor.moveToNext(); 19 | id = cursor.getInt(0); 20 | cursor.close(); 21 | } 22 | return id == 1; 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return "RTree Test"; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/RawExecSQLExceptionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.util.Log; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteException; 6 | import net.zetetic.ZeteticApplication; 7 | import net.zetetic.tests.SQLCipherTest; 8 | 9 | public class RawExecSQLExceptionTest extends SupportTest { 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | 14 | try { 15 | database.rawExecSQL("select foo from bar"); 16 | } catch (SQLiteException e) { 17 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteException", e); 18 | String message = e.getMessage(); 19 | setMessage(message); 20 | if (!message.matches("no such table: bar")) { 21 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 22 | return false; 23 | } 24 | return true; 25 | } catch (Exception e) { 26 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 27 | return false; 28 | } 29 | 30 | return false; 31 | } 32 | 33 | @Override 34 | public String getName() { 35 | return "rawExecSQL Exception Test"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/RawExecSQLTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class RawExecSQLTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | 11 | String actual = ""; 12 | String value = "hey"; 13 | database.rawExecSQL("create table t1(a)"); 14 | database.execSQL("insert into t1(a) values (?)", new Object[]{value}); 15 | Cursor result = database.rawQuery("select * from t1", new String[]{}); 16 | if(result != null){ 17 | result.moveToFirst(); 18 | actual = result.getString(0); 19 | result.close(); 20 | } 21 | return actual.equals(value); 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return "rawExecSQL Test"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/RawQueryNoSuchFunctionErrorMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.Cursor; 4 | import android.util.Log; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import android.database.sqlite.SQLiteException; 7 | import net.zetetic.ZeteticApplication; 8 | import net.zetetic.tests.SQLCipherTest; 9 | 10 | public class RawQueryNoSuchFunctionErrorMessageTest extends SupportTest { 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | try { 15 | Cursor ignored = database.rawQuery("SELECT UPER('Test')", null); 16 | } catch (SQLiteException e) { 17 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteException", e); 18 | String message = e.getMessage(); 19 | setMessage(message); 20 | // TBD missing error code etc. 21 | if (!message.matches("no such function: UPER: .*\\, while compiling: SELECT UPER\\('Test'\\)")) { 22 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 23 | return false; 24 | } 25 | return true; 26 | } catch (Exception e) { 27 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 28 | return false; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | @Override 35 | public String getName() { 36 | return "rawQuery no such function error message Test"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/RawQueryNonsenseStatementErrorMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.Cursor; 4 | import android.util.Log; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import android.database.sqlite.SQLiteException; 7 | import net.zetetic.ZeteticApplication; 8 | import net.zetetic.tests.SQLCipherTest; 9 | 10 | public class RawQueryNonsenseStatementErrorMessageTest extends SupportTest { 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | try { 15 | Cursor ignored = database.rawQuery("101", null); 16 | } catch (SQLiteException e) { 17 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteException", e); 18 | String message = e.getMessage(); 19 | setMessage(message); 20 | // TBD missing error code etc. 21 | if (!message.matches("near \"101\": syntax error: .*\\, while compiling: 101")) { 22 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 23 | return false; 24 | } 25 | return true; 26 | } catch (Exception e) { 27 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 28 | return false; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | @Override 35 | public String getName() { 36 | return "rawQuery nonsense statement error message Test"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/RawQuerySyntaxErrorMessageTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.database.Cursor; 4 | import android.util.Log; 5 | import net.sqlcipher.database.SQLiteDatabase; 6 | import android.database.sqlite.SQLiteException; 7 | import net.zetetic.ZeteticApplication; 8 | import net.zetetic.tests.SQLCipherTest; 9 | 10 | public class RawQuerySyntaxErrorMessageTest extends SupportTest { 11 | 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | try { 15 | Cursor ignored = database.rawQuery("SLCT 1", null); 16 | } catch (SQLiteException e) { 17 | Log.v(ZeteticApplication.TAG, "EXPECTED RESULT: DID throw SQLiteException", e); 18 | String message = e.getMessage(); 19 | setMessage(message); 20 | // TBD missing error code etc. 21 | if (!message.matches("near \"SLCT\": syntax error: .*\\, while compiling: SLCT 1")) { 22 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: INCORRECT exception message: " + message); 23 | return false; 24 | } 25 | return true; 26 | } catch (Exception e) { 27 | Log.e(ZeteticApplication.TAG, "NOT EXPECTED: DID throw other exception", e); 28 | return false; 29 | } 30 | 31 | return false; 32 | } 33 | 34 | @Override 35 | public String getName() { 36 | return "rawQuery syntax error message Test"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/RawQueryTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class RawQueryTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | int rows = 0; 12 | database.execSQL("create table t1(a,b);"); 13 | database.execSQL("insert into t1(a,b) values(?, ?);", 14 | new Object[]{"one for the money", "two for the show"}); 15 | Cursor cursor = database.rawQuery("select * from t1;", null, 1, 1); 16 | if(cursor != null){ 17 | while(cursor.moveToNext()) { 18 | cursor.getString(0); 19 | rows++; 20 | } 21 | cursor.close(); 22 | } 23 | return rows > 0; 24 | } 25 | 26 | @Override 27 | public String getName() { 28 | return "Raw Query Test"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/ReadWriteUserVersionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.tests.SQLCipherTest; 5 | 6 | public class ReadWriteUserVersionTest extends SupportTest { 7 | @Override 8 | public boolean execute(SQLiteDatabase database) { 9 | int version = 4; 10 | database.setVersion(version); 11 | int readVersion = database.getVersion(); 12 | return version == readVersion; 13 | } 14 | 15 | @Override 16 | public String getName() { 17 | return "Read/write user_version"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/ReadWriteWriteAheadLoggingTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class ReadWriteWriteAheadLoggingTest extends SupportTest { 8 | @Override 9 | public boolean execute(final SQLiteDatabase database) { 10 | 11 | try { 12 | final int[] a = new int[1]; 13 | final int[] b = new int[1]; 14 | database.setLockingEnabled(false); 15 | boolean walEnabled = database.enableWriteAheadLogging(); 16 | if (!walEnabled) return false; 17 | 18 | //database.execSQL("PRAGMA read_uncommitted = 1;"); 19 | 20 | database.execSQL("CREATE TABLE t1(a,b)"); 21 | database.rawQuery("INSERT INTO t1(a,b) VALUES(?,?);", new Object[]{1, 2}); 22 | database.beginTransaction(); 23 | //database.beginTransactionNonExclusive(); 24 | database.rawQuery("DELETE FROM t1 WHERE a = ?;", new Object[]{1}); 25 | Thread t = new Thread(new Runnable() { 26 | @Override 27 | public void run() { 28 | Cursor cursor = database.rawQuery("SELECT COUNT(*) FROM t1 WHERE a = ?;", new Object[]{1}); 29 | if (cursor != null && cursor.moveToFirst()) { 30 | a[0] = cursor.getInt(0); 31 | b[0] = cursor.getInt(0); 32 | log(String.format("Retrieved %d rows back", a[0])); 33 | } 34 | } 35 | }); 36 | t.start(); 37 | t.join(); 38 | database.setTransactionSuccessful(); 39 | database.endTransaction(); 40 | //return a[0] == 1 && b[0] == 2; 41 | return a[0] == 0 && b[0] == 0; 42 | } catch (InterruptedException ex){ 43 | return false; 44 | } 45 | } 46 | 47 | @Override 48 | public String getName() { 49 | return "Read/Write WAL Test"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/SQLiteOpenHelperEnableWriteAheadLogBeforeGetDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.sqlcipher.database.SupportFactory; 5 | import net.zetetic.ZeteticApplication; 6 | import net.zetetic.tests.TestResult; 7 | import androidx.sqlite.db.SupportSQLiteDatabase; 8 | import androidx.sqlite.db.SupportSQLiteOpenHelper; 9 | 10 | public class SQLiteOpenHelperEnableWriteAheadLogBeforeGetDatabaseTest implements ISupportTest { 11 | @Override 12 | public TestResult run() { 13 | TestResult result = new TestResult(getName(), false); 14 | 15 | byte[] passphrase = SQLiteDatabase.getBytes(ZeteticApplication.DATABASE_PASSWORD.toCharArray()); 16 | SupportFactory factory = new SupportFactory(passphrase); 17 | SupportSQLiteOpenHelper.Configuration cfg = 18 | SupportSQLiteOpenHelper.Configuration.builder(ZeteticApplication.getInstance()) 19 | .name(ZeteticApplication.DATABASE_NAME) 20 | .callback(new SupportSQLiteOpenHelper.Callback(1) { 21 | @Override 22 | public void onCreate(SupportSQLiteDatabase db) { 23 | // unused 24 | } 25 | 26 | @Override 27 | public void onUpgrade(SupportSQLiteDatabase db, int oldVersion, 28 | int newVersion) { 29 | // unused 30 | } 31 | }) 32 | .build(); 33 | SupportSQLiteOpenHelper helper = factory.create(cfg); 34 | helper.setWriteAheadLoggingEnabled(true); 35 | 36 | SupportSQLiteDatabase database = helper.getWritableDatabase(); 37 | result.setResult(database.isWriteAheadLoggingEnabled()); 38 | helper.close(); 39 | 40 | return result; 41 | } 42 | 43 | @Override 44 | public String getName() { 45 | return "SQLiteOpenHelper Enable WAL Before Get DB"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/SQLiteOpenHelperGetNameTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.content.Context; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.sqlcipher.database.SQLiteOpenHelper; 6 | import net.zetetic.ZeteticApplication; 7 | import net.zetetic.tests.SQLCipherTest; 8 | import java.io.File; 9 | import java.util.UUID; 10 | 11 | public class SQLiteOpenHelperGetNameTest extends SupportTest { 12 | @Override 13 | public boolean execute(SQLiteDatabase database) { 14 | UUID name = UUID.randomUUID(); 15 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(name.toString()); 16 | DatabaseHelper helper = new DatabaseHelper(ZeteticApplication.getInstance(), 17 | databasePath.getAbsolutePath()); 18 | return databasePath.getAbsolutePath().equals(helper.getDatabaseName()); 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "SQLiteOpenHelper GetName Test"; 24 | } 25 | 26 | class DatabaseHelper extends SQLiteOpenHelper { 27 | 28 | public DatabaseHelper(Context context, String databasePath) { 29 | super(context, databasePath, null, 1); 30 | } 31 | 32 | @Override 33 | public void onCreate(SQLiteDatabase database) { } 34 | 35 | @Override 36 | public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion){} 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/SoundexTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class SoundexTest extends SupportTest { 8 | 9 | String SQLCIPHER_SOUNDEX = "S421"; 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | String soundex = QueryHelper.singleValueFromQuery(database, "SELECT soundex('sqlcipher');"); 14 | return SQLCIPHER_SOUNDEX.equals(soundex); 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return "Soundex Test"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/StatusMemoryUsedTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.tests.SQLCipherTest; 5 | 6 | public class StatusMemoryUsedTest extends SupportTest { 7 | 8 | public static final int SQLITE_STATUS_MEMORY_USED = 0; 9 | 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | 13 | int originalMemory = database.status(SQLITE_STATUS_MEMORY_USED, false); 14 | database.execSQL("create table t1(a,b)"); 15 | database.execSQL("insert into t1(a,b) values(?, ?)", 16 | new Object[]{"one for the money", "two for the show"}); 17 | int currentMemory = database.status(SQLITE_STATUS_MEMORY_USED, false); 18 | return originalMemory != currentMemory; 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "Status Memory Used Test"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/TextAsDoubleTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class TextAsDoubleTest extends SupportTest { 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.execSQL("create table t1(a TEXT);"); 11 | database.execSQL("insert into t1(a) values(3.14159265359);"); 12 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 13 | if(cursor != null){ 14 | cursor.moveToFirst(); 15 | double value = cursor.getDouble(0); 16 | return value == 3.14159265359; 17 | } 18 | return false; 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "Text As Double Test"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/TextAsIntegerTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class TextAsIntegerTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | database.execSQL("create table t1(a TEXT);"); 12 | database.execSQL("insert into t1(a) values(15);"); 13 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 14 | if(cursor != null){ 15 | cursor.moveToFirst(); 16 | int value = cursor.getInt(0); 17 | return value == 15; 18 | } 19 | return false; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return "Text as Integer Test"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/TextAsLongTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.Cursor; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class TextAsLongTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | database.execSQL("create table t1(a TEXT, b TEXT);"); 12 | database.execSQL("insert into t1(a,b) values(500, 500);"); 13 | Cursor cursor = database.rawQuery("select * from t1;", new String[]{}); 14 | if(cursor != null){ 15 | cursor.moveToFirst(); 16 | long value = cursor.getLong(0); 17 | return value == 500; 18 | } 19 | return false; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return "Text as Long Test"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/TransactionNonExclusiveTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.tests.SQLCipherTest; 5 | 6 | public class TransactionNonExclusiveTest extends SupportTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.beginTransactionNonExclusive(); 11 | database.execSQL("create table t1(a,b);"); 12 | database.setTransactionSuccessful(); 13 | database.endTransaction(); 14 | return true; 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return "Transaction Immediate Mode"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/TransactionWithListenerTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.sqlcipher.database.SQLiteTransactionListener; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class TransactionWithListenerTest extends SupportTest { 8 | 9 | boolean beginCalled = false; 10 | 11 | @Override 12 | public boolean execute(SQLiteDatabase database) { 13 | database.beginTransactionWithListener(listener); 14 | database.execSQL("create table t1(a,b);"); 15 | database.setTransactionSuccessful(); 16 | database.endTransaction(); 17 | return beginCalled; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return "Transaction Exclusive Mode"; 23 | } 24 | 25 | SQLiteTransactionListener listener = new SQLiteTransactionListener() { 26 | @Override 27 | public void onBegin() { 28 | beginCalled = true; 29 | } 30 | 31 | @Override 32 | public void onCommit() { 33 | 34 | } 35 | 36 | @Override 37 | public void onRollback() { 38 | 39 | } 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/UnicodeTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import android.util.Log; 4 | import net.sqlcipher.database.SQLiteDatabase; 5 | import net.sqlcipher.database.SQLiteStatement; 6 | import net.zetetic.tests.SQLCipherTest; 7 | 8 | public class UnicodeTest extends SupportTest { 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | //if (android.os.Build.VERSION.SDK_INT >= 23) { // Android M 12 | // This will crash on Android releases 1.X-5.X due the following Android bug: 13 | // https://code.google.com/p/android/issues/detail?id=81341 14 | SQLiteStatement st = database.compileStatement("SELECT '\uD83D\uDE03'"); // SMILING FACE (MOUTH OPEN) 15 | String res = st.simpleQueryForString(); 16 | String message = String.format("Returned value:%s", res); 17 | setMessage(message); 18 | Log.i(TAG, message); 19 | return res.equals("\uD83D\uDE03"); 20 | //} 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return "Unicode Test"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/VerifyCipherProviderTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class VerifyCipherProviderTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | String provider = QueryHelper.singleValueFromQuery(database, 12 | "PRAGMA cipher_provider;"); 13 | setMessage(String.format("Reported:%s", provider)); 14 | return provider.contains("openssl"); 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return "Verify Cipher Provider Test"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/VerifyCipherProviderVersionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.QueryHelper; 5 | import net.zetetic.tests.SQLCipherTest; 6 | 7 | public class VerifyCipherProviderVersionTest extends SupportTest { 8 | 9 | @Override 10 | public boolean execute(SQLiteDatabase database) { 11 | String provider = QueryHelper.singleValueFromQuery(database, 12 | "PRAGMA cipher_provider_version;"); 13 | setMessage(String.format("Reported:%s", provider)); 14 | return provider.contains("OpenSSL 1.1.1") || 15 | provider.contains("OpenSSL 1.0.2u-fips"); 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return "Verify Cipher Provider Version"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/WriteAheadLoggingWithAttachedDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.ZeteticApplication; 5 | import net.zetetic.tests.SQLCipherTest; 6 | import java.io.File; 7 | import java.util.UUID; 8 | 9 | public class WriteAheadLoggingWithAttachedDatabaseTest extends SupportTest { 10 | @Override 11 | public boolean execute(SQLiteDatabase database) { 12 | UUID name = UUID.randomUUID(); 13 | File databasePath = ZeteticApplication.getInstance().getDatabasePath(name.toString()); 14 | database.execSQL("ATTACH DATABASE ? as foo;", new Object[]{databasePath.getAbsolutePath()}); 15 | boolean result = database.enableWriteAheadLogging(); 16 | return result == false; 17 | } 18 | 19 | @Override 20 | public String getName() { 21 | return "Disallow WAL Mode with Attached DB"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/WriteAheadLoggingWithInMemoryDatabaseTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.sqlcipher.database.SupportFactory; 5 | import net.zetetic.ZeteticApplication; 6 | import net.zetetic.tests.SQLCipherTest; 7 | import net.zetetic.tests.TestResult; 8 | import androidx.sqlite.db.SupportSQLiteDatabase; 9 | import androidx.sqlite.db.SupportSQLiteOpenHelper; 10 | 11 | public class WriteAheadLoggingWithInMemoryDatabaseTest implements ISupportTest { 12 | @Override 13 | public TestResult run() { 14 | TestResult result = new TestResult(getName(), false); 15 | 16 | byte[] passphrase = SQLiteDatabase.getBytes(ZeteticApplication.DATABASE_PASSWORD.toCharArray()); 17 | SupportFactory factory = new SupportFactory(passphrase); 18 | SupportSQLiteOpenHelper.Configuration cfg = 19 | SupportSQLiteOpenHelper.Configuration.builder(ZeteticApplication.getInstance()) 20 | .name(null) 21 | .callback(new SupportSQLiteOpenHelper.Callback(1) { 22 | @Override 23 | public void onCreate(SupportSQLiteDatabase db) { 24 | // unused 25 | } 26 | 27 | @Override 28 | public void onUpgrade(SupportSQLiteDatabase db, int oldVersion, 29 | int newVersion) { 30 | // unused 31 | } 32 | }) 33 | .build(); 34 | SupportSQLiteOpenHelper helper = factory.create(cfg); 35 | SupportSQLiteDatabase database = helper.getWritableDatabase(); 36 | 37 | result.setResult(!database.enableWriteAheadLogging()); 38 | 39 | helper.close(); 40 | 41 | return result; 42 | } 43 | 44 | @Override 45 | public String getName() { 46 | return "Disallow WAL Mode with in memory DB"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/net/zetetic/tests/support/WriteAheadLoggingWithTransactionTest.java: -------------------------------------------------------------------------------- 1 | package net.zetetic.tests.support; 2 | 3 | import net.sqlcipher.database.SQLiteDatabase; 4 | import net.zetetic.tests.SQLCipherTest; 5 | 6 | public class WriteAheadLoggingWithTransactionTest extends SupportTest { 7 | 8 | @Override 9 | public boolean execute(SQLiteDatabase database) { 10 | database.beginTransaction(); 11 | try { 12 | database.enableWriteAheadLogging(); 13 | } catch (IllegalStateException ex){ 14 | if(ex.getMessage().equals("Write Ahead Logging cannot be enabled while in a transaction")) { 15 | return true; 16 | } 17 | } 18 | return false; 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return "Disallow WAL Mode while in transaction"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/res/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/res/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqlcipher/sqlcipher-android-tests/2e5d2c1929ba18aeb6e7693839a8474811629d42/app/src/main/res/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /app/src/main/res/layout/cursor_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 |