Skip to content

Commit

Permalink
Merge pull request #41 from garymathews/TIMOB-27430
Browse files Browse the repository at this point in the history
fix(android): null value incorrectly interpreted as boolean
  • Loading branch information
garymathews committed Oct 10, 2019
2 parents 7e71998 + e7d53b2 commit d85e5fd
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
library 'pipeline-library'

buildModule {
sdkVersion = '7.5.2.GA'
sdkVersion = '8.2.0.GA'
}
4 changes: 4 additions & 0 deletions android/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="appcelerator.encrypteddatabase" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="14" />
</manifest>
23 changes: 23 additions & 0 deletions android/encrypteddatabase.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Android">
<configuration>
<option name="PROJECT_TYPE" value="1" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="sqlcipher" level="project" />
<orderEntry type="module" module-name="common" scope="PROVIDED" />
<orderEntry type="module" module-name="kroll-apt" scope="PROVIDED" />
<orderEntry type="module" module-name="titanium" scope="PROVIDED" />
</component>
</module>
Binary file modified android/lib/sqlcipher.jar
Binary file not shown.
Binary file modified android/libs/arm64-v8a/libsqlcipher.so
Binary file not shown.
Binary file modified android/libs/armeabi-v7a/libsqlcipher.so
Binary file not shown.
Binary file modified android/libs/x86/libsqlcipher.so
Binary file not shown.
2 changes: 1 addition & 1 deletion android/manifest
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# this is your module manifest and used by Titanium
# during compilation, packaging, distribution, etc.
#
version: 3.0.4
version: 3.1.0
apiversion: 4
architectures: arm64-v8a armeabi-v7a x86
description: Provides transparent, secure 256-bit AES encryption of SQLite database files.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
import org.appcelerator.titanium.TiFileProxy;
import org.appcelerator.titanium.io.TiBaseFile;
import org.appcelerator.titanium.io.TiFileFactory;
import org.appcelerator.titanium.util.TiConvert;
import org.appcelerator.titanium.util.TiUrl;

import android.app.Activity;
import android.content.Context;

import net.sqlcipher.SQLException;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabaseHook;

@Kroll.module(name = "Encrypteddatabase", id = "appcelerator.encrypteddatabase")
public class EncrypteddatabaseModule extends KrollModule {
Expand Down Expand Up @@ -64,6 +64,15 @@ public void setPassword(String value) {
public TiDatabaseProxy open(Object file) {
// Attempt to create/open the given database file/name.
TiDatabaseProxy dbp = null;

// Migrate database if necessary.
final SQLiteDatabaseHook migrationHook = new SQLiteDatabaseHook() {
public void preKey(SQLiteDatabase database) {}
public void postKey(SQLiteDatabase database) {
database.rawExecSQL("PRAGMA cipher_migrate;");
}
};

if (file instanceof TiFileProxy) {
// File support is read-only for now. The NO_LOCALIZED_COLLATORS
// flag means the database doesn't have Android metadata (i.e.
Expand All @@ -73,7 +82,7 @@ public TiDatabaseProxy open(Object file) {
Log.d(TAG, "Opening database from filesystem: " + absolutePath);

SQLiteDatabase db = SQLiteDatabase.openDatabase(absolutePath, getPassword(), null,
SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS, migrationHook);
if (db != null) {
dbp = new TiDatabaseProxy(db);
} else {
Expand All @@ -83,7 +92,7 @@ public TiDatabaseProxy open(Object file) {
String name = (String) file;
File dbPath = TiApplication.getInstance().getDatabasePath(name);
dbPath.getParentFile().mkdirs();
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbPath, getPassword(), null);
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbPath, getPassword(), null, migrationHook);
if (db != null) {
dbp = new TiDatabaseProxy(name, db);
} else {
Expand Down
24 changes: 11 additions & 13 deletions android/src/appcelerator/encrypteddatabase/TiResultSetProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.appcelerator.titanium.util.TiConvert;

import android.database.Cursor;
import net.sqlcipher.CrossProcessCursorWrapper;
import net.sqlcipher.AbstractWindowedCursor;
import net.sqlcipher.SQLException;
import android.os.Build;

Expand Down Expand Up @@ -95,16 +95,16 @@ private Object internalGetField(int index, int type) {
boolean fromString = false;

try {
if (rs instanceof CrossProcessCursorWrapper) {
CrossProcessCursorWrapper cursor = (CrossProcessCursorWrapper) rs;
int columnType = cursor.getType(index);
if (columnType == android.database.Cursor.FIELD_TYPE_FLOAT) {
if (rs instanceof AbstractWindowedCursor) {
AbstractWindowedCursor cursor = (AbstractWindowedCursor) rs;

if (cursor.isFloat(index)) {
result = cursor.getDouble(index);
} else if (columnType == android.database.Cursor.FIELD_TYPE_INTEGER) {
} else if (cursor.isLong(index)) {
result = cursor.getLong(index);
} else if (columnType == android.database.Cursor.FIELD_TYPE_NULL) {
} else if (cursor.isNull(index)) {
result = null;
} else if (columnType == android.database.Cursor.FIELD_TYPE_BLOB) {
} else if (cursor.isBlob(index)) {
result = TiBlob.blobFromData(cursor.getBlob(index));
} else {
fromString = true;
Expand All @@ -123,11 +123,9 @@ private Object internalGetField(int index, int type) {
throw new IllegalStateException("Requested column number " + index + " does not exist");
}
} catch (RuntimeException e) {
// Both SQLException and IllegalStateException (exceptions known to
// occur
// Both SQLException and IllegalStateException (exceptions known to occur
// in this block) are RuntimeExceptions and since we anyway re-throw
// and log the same error message, we're just catching all
// RuntimeExceptions.
// and log the same error message, we're just catching all RuntimeExceptions.
Log.e(TAG, "Exception getting value for column " + index + ": " + e.getMessage(), e);
throw e;
}
Expand All @@ -139,7 +137,7 @@ private Object internalGetField(int index, int type) {
}
break;
case EncrypteddatabaseModule.FIELD_TYPE_INT:
if (!(result instanceof Integer)) {
if (!(result instanceof Integer) && !(result instanceof Long)) {
result = TiConvert.toInt(result);
}
break;
Expand Down
2 changes: 1 addition & 1 deletion test/unit/specs/int.boundary.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ describe('appcelerator.encrypteddatabase', function () {
const resultSet = dbConnection.execute('SELECT id, intValue FROM intTable ORDER BY id');
expect(resultSet.rowCount).toEqual(rows.length);
for (let index = 0; resultSet.isValidRow(); resultSet.next(), index++) {
expect(resultSet.field(1)).toEqual(rows[index]);
expect(parseInt(resultSet.field(1))).toEqual(rows[index]);
}
dbConnection.close();
});
Expand Down

0 comments on commit d85e5fd

Please sign in to comment.