From d59b3a4439beda5cd3e6b67812d17f893a357c9f Mon Sep 17 00:00:00 2001 From: Rahul Behera Date: Fri, 15 Sep 2017 17:39:40 -0500 Subject: [PATCH 1/5] check characterset --- .../network/NetworkEventReporterImpl.java | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java b/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java index 5b0a5213..a083cd3c 100644 --- a/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java +++ b/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java @@ -10,22 +10,31 @@ package com.facebook.stetho.inspector.network; import android.os.SystemClock; + import com.facebook.stetho.common.Utf8Charset; import com.facebook.stetho.inspector.console.CLog; import com.facebook.stetho.inspector.protocol.module.Console; import com.facebook.stetho.inspector.protocol.module.Network; import com.facebook.stetho.inspector.protocol.module.Page; + import org.json.JSONException; import org.json.JSONObject; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicInteger; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * Implementation of {@link NetworkEventReporter} which allows callers to inform the Stetho * system of network traffic. Callers can safely eagerly access this class and store a @@ -39,6 +48,8 @@ public class NetworkEventReporterImpl implements NetworkEventReporter { private static NetworkEventReporter sInstance; + private static final CharsetDecoder decoder = Charset.forName(Utf8Charset.NAME).newDecoder(); + private NetworkEventReporterImpl() { } @@ -49,6 +60,8 @@ private NetworkEventReporterImpl() { public static synchronized NetworkEventReporter get() { if (sInstance == null) { sInstance = new NetworkEventReporterImpl(); + decoder.onUnmappableCharacter(CodingErrorAction.REPORT); + decoder.onMalformedInput(CodingErrorAction.REPORT); } return sInstance; } @@ -115,15 +128,24 @@ private static String readBodyAsString( InspectorRequest request) { try { byte[] body = request.body(); - if (body != null) { - return new String(body, Utf8Charset.INSTANCE); + try { + CharBuffer charBuffer = decoder.decode(ByteBuffer.wrap(body)); + return charBuffer.toString(); + } catch (CharacterCodingException e) { + CLog.writeToConsole( + peerManager, + Console.MessageLevel.WARNING, + Console.MessageSource.NETWORK, + "Could not reproduce POST body do to a an invalid charset: " + e); + return "Data (length:" +" cannot be represented as a string."; } } catch (IOException | OutOfMemoryError e) { CLog.writeToConsole( - peerManager, - Console.MessageLevel.WARNING, - Console.MessageSource.NETWORK, - "Could not reproduce POST body: " + e); + peerManager, + Console.MessageLevel.WARNING, + Console.MessageSource.NETWORK, + "Could not reproduce POST body: " + e); + } return null; } From f78e544798ecdead4c97449517cf63910c30d533 Mon Sep 17 00:00:00 2001 From: Rahul Behera Date: Fri, 15 Sep 2017 17:56:22 -0500 Subject: [PATCH 2/5] no message --- .../stetho/inspector/network/NetworkEventReporterImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java b/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java index a083cd3c..80294a24 100644 --- a/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java +++ b/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java @@ -137,7 +137,7 @@ private static String readBodyAsString( Console.MessageLevel.WARNING, Console.MessageSource.NETWORK, "Could not reproduce POST body do to a an invalid charset: " + e); - return "Data (length:" +" cannot be represented as a string."; + return "Data (length:"+ body.length +") cannot be represented as a string."; } } catch (IOException | OutOfMemoryError e) { CLog.writeToConsole( From 561f7f7ee6614904c0768ab10006cb805b6cbf2d Mon Sep 17 00:00:00 2001 From: Rahul Behera Date: Fri, 15 Sep 2017 18:06:16 -0500 Subject: [PATCH 3/5] update error messages --- .../inspector/network/NetworkEventReporterImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java b/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java index 80294a24..1e6b3520 100644 --- a/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java +++ b/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java @@ -132,19 +132,21 @@ private static String readBodyAsString( CharBuffer charBuffer = decoder.decode(ByteBuffer.wrap(body)); return charBuffer.toString(); } catch (CharacterCodingException e) { + String logMessage = "Charset in POST/PUT is not UTF-8. Data (length:"+ body.length + +") cannot be represented as a string. "; CLog.writeToConsole( peerManager, Console.MessageLevel.WARNING, Console.MessageSource.NETWORK, - "Could not reproduce POST body do to a an invalid charset: " + e); - return "Data (length:"+ body.length +") cannot be represented as a string."; + logMessage + e); + return logMessage; } } catch (IOException | OutOfMemoryError e) { CLog.writeToConsole( peerManager, Console.MessageLevel.WARNING, Console.MessageSource.NETWORK, - "Could not reproduce POST body: " + e); + "Could not reproduce POST/PUT body: " + e); } return null; From d603cf381e07ee014312cad98ac5e170998b0880 Mon Sep 17 00:00:00 2001 From: Rahul Behera Date: Mon, 18 Sep 2017 09:53:18 -0500 Subject: [PATCH 4/5] NPE check --- .../stetho/inspector/network/NetworkEventReporterImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java b/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java index 1e6b3520..4e6690f0 100644 --- a/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java +++ b/stetho/src/main/java/com/facebook/stetho/inspector/network/NetworkEventReporterImpl.java @@ -128,6 +128,9 @@ private static String readBodyAsString( InspectorRequest request) { try { byte[] body = request.body(); + if (body == null || body.length == 0) { + return ""; + } try { CharBuffer charBuffer = decoder.decode(ByteBuffer.wrap(body)); return charBuffer.toString(); From fa44a9072c9c1ff697fded78edbbbff66735c769 Mon Sep 17 00:00:00 2001 From: Arik Yaacob Date: Mon, 16 Oct 2017 16:04:51 -0500 Subject: [PATCH 5/5] switch to SQLCipher --- build.gradle | 2 +- stetho/build.gradle | 1 + .../main/java/com/facebook/stetho/Stetho.java | 4 +++- .../database/DatabaseConnectionProvider.java | 3 ++- .../DefaultDatabaseConnectionProvider.java | 7 +++++-- .../database/SQLiteDatabaseCompat.java | 18 ++++++++++-------- .../database/SqliteDatabaseDriver.java | 10 +++++++--- 7 files changed, 29 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 3f806cd7..e52ed0ac 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:2.3.3' } } diff --git a/stetho/build.gradle b/stetho/build.gradle index 34aa743c..8ad1031f 100644 --- a/stetho/build.gradle +++ b/stetho/build.gradle @@ -19,6 +19,7 @@ dependencies { compile 'com.google.code.findbugs:jsr305:2.0.1' compile 'com.android.support:appcompat-v7:23.0.1' // optional + compile 'net.zetetic:android-database-sqlcipher:3.5.7@aar' testCompile 'junit:junit:4.12' testCompile('org.robolectric:robolectric:2.4') { diff --git a/stetho/src/main/java/com/facebook/stetho/Stetho.java b/stetho/src/main/java/com/facebook/stetho/Stetho.java index 592c7ccd..4ca29117 100644 --- a/stetho/src/main/java/com/facebook/stetho/Stetho.java +++ b/stetho/src/main/java/com/facebook/stetho/Stetho.java @@ -82,6 +82,7 @@ * the {@code stetho-sample} for more information. */ public class Stetho { + public static String password = ""; private Stetho() { } @@ -101,7 +102,8 @@ public static InitializerBuilder newInitializerBuilder(Context context) { * first socket connection is received, allowing this to be safely used for debug builds on * even low-end hardware without noticeably affecting performance. */ - public static void initializeWithDefaults(final Context context) { + public static void initializeWithDefaults(final Context context, String password) { + Stetho.password = password; initialize(new Initializer(context) { @Override protected Iterable getDumperPlugins() { diff --git a/stetho/src/main/java/com/facebook/stetho/inspector/database/DatabaseConnectionProvider.java b/stetho/src/main/java/com/facebook/stetho/inspector/database/DatabaseConnectionProvider.java index 7f19d81e..def9c875 100644 --- a/stetho/src/main/java/com/facebook/stetho/inspector/database/DatabaseConnectionProvider.java +++ b/stetho/src/main/java/com/facebook/stetho/inspector/database/DatabaseConnectionProvider.java @@ -9,7 +9,8 @@ package com.facebook.stetho.inspector.database; -import android.database.sqlite.SQLiteDatabase; +//import android.database.sqlite.SQLiteDatabase; +import net.sqlcipher.database.SQLiteDatabase; import android.database.sqlite.SQLiteException; import java.io.File; diff --git a/stetho/src/main/java/com/facebook/stetho/inspector/database/DefaultDatabaseConnectionProvider.java b/stetho/src/main/java/com/facebook/stetho/inspector/database/DefaultDatabaseConnectionProvider.java index 103218a1..9f9df39c 100644 --- a/stetho/src/main/java/com/facebook/stetho/inspector/database/DefaultDatabaseConnectionProvider.java +++ b/stetho/src/main/java/com/facebook/stetho/inspector/database/DefaultDatabaseConnectionProvider.java @@ -9,13 +9,16 @@ package com.facebook.stetho.inspector.database; -import android.database.sqlite.SQLiteDatabase; +//import android.database.sqlite.SQLiteDatabase; +import net.sqlcipher.database.SQLiteDatabase; import android.database.sqlite.SQLiteException; import com.facebook.stetho.inspector.database.SQLiteDatabaseCompat.SQLiteOpenOptions; import java.io.File; +import static com.facebook.stetho.Stetho.password; + /** * Opens the requested database using * {@link SQLiteDatabase#openDatabase(String, SQLiteDatabase.CursorFactory, int)} directly. @@ -62,7 +65,7 @@ protected SQLiteDatabase performOpen(File databaseFile, @SQLiteOpenOptions int o flags |= compatInstance.provideOpenFlags(options); SQLiteDatabase db = SQLiteDatabase.openDatabase( - databaseFile.getAbsolutePath(), + databaseFile.getAbsolutePath(), password, null /* cursorFactory */, flags); compatInstance.enableFeatures(options, db); diff --git a/stetho/src/main/java/com/facebook/stetho/inspector/database/SQLiteDatabaseCompat.java b/stetho/src/main/java/com/facebook/stetho/inspector/database/SQLiteDatabaseCompat.java index 6e1c9f55..c512cb6d 100644 --- a/stetho/src/main/java/com/facebook/stetho/inspector/database/SQLiteDatabaseCompat.java +++ b/stetho/src/main/java/com/facebook/stetho/inspector/database/SQLiteDatabaseCompat.java @@ -10,7 +10,8 @@ package com.facebook.stetho.inspector.database; import android.annotation.TargetApi; -import android.database.sqlite.SQLiteDatabase; +//import android.database.sqlite.SQLiteDatabase; +import net.sqlcipher.database.SQLiteDatabase; import android.os.Build; import android.support.annotation.IntDef; @@ -31,9 +32,10 @@ public abstract class SQLiteDatabaseCompat { private static final SQLiteDatabaseCompat sInstance; static { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - sInstance = new JellyBeanAndBeyondImpl(); - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { +// sInstance = new JellyBeanAndBeyondImpl(); +// } else + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { sInstance = new HoneycombImpl(); } else { sInstance = new NoopImpl(); @@ -47,7 +49,7 @@ public static SQLiteDatabaseCompat getInstance() { public abstract int provideOpenFlags(@SQLiteOpenOptions int openOptions); public abstract void enableFeatures(@SQLiteOpenOptions int openOptions, SQLiteDatabase db); - @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + /*@TargetApi(Build.VERSION_CODES.JELLY_BEAN) private static class JellyBeanAndBeyondImpl extends SQLiteDatabaseCompat { @Override public int provideOpenFlags(@SQLiteOpenOptions int openOptions) { @@ -64,9 +66,9 @@ public void enableFeatures(@SQLiteOpenOptions int openOptions, SQLiteDatabase db db.setForeignKeyConstraintsEnabled(true); } } - } + }*/ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) + // @TargetApi(Build.VERSION_CODES.HONEYCOMB) private static class HoneycombImpl extends SQLiteDatabaseCompat { @Override public int provideOpenFlags(@SQLiteOpenOptions int openOptions) { @@ -76,7 +78,7 @@ public int provideOpenFlags(@SQLiteOpenOptions int openOptions) { @Override public void enableFeatures(@SQLiteOpenOptions int openOptions, SQLiteDatabase db) { if ((openOptions & ENABLE_WRITE_AHEAD_LOGGING) != 0) { - db.enableWriteAheadLogging(); + db.execSQL("PRAGMA journal_mode=WAL;"); } if ((openOptions & ENABLE_FOREIGN_KEY_CONSTRAINTS) != 0) { diff --git a/stetho/src/main/java/com/facebook/stetho/inspector/database/SqliteDatabaseDriver.java b/stetho/src/main/java/com/facebook/stetho/inspector/database/SqliteDatabaseDriver.java index 75b80076..813834ba 100644 --- a/stetho/src/main/java/com/facebook/stetho/inspector/database/SqliteDatabaseDriver.java +++ b/stetho/src/main/java/com/facebook/stetho/inspector/database/SqliteDatabaseDriver.java @@ -12,9 +12,12 @@ import android.annotation.TargetApi; import android.content.Context; import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteException; -import android.database.sqlite.SQLiteStatement; +//import android.database.sqlite.SQLiteDatabase; +import net.sqlcipher.database.SQLiteDatabase; +import net.sqlcipher.database.SQLiteException; +import net.sqlcipher.database.SQLiteStatement; +//import android.database.sqlite.SQLiteException; +//import android.database.sqlite.SQLiteStatement; import com.facebook.stetho.common.Util; import com.facebook.stetho.inspector.protocol.module.Database; @@ -57,6 +60,7 @@ public SqliteDatabaseDriver(Context context) { context, new DefaultDatabaseFilesProvider(context), new DefaultDatabaseConnectionProvider()); + SQLiteDatabase.loadLibs(context); } /**