Log more specific database exceptions.

fork-5.53.8
Greyson Parrelli 2021-10-19 16:38:08 -04:00
rodzic 13ef53372e
commit 00c131355f
2 zmienionych plików z 47 dodań i 9 usunięć

Wyświetl plik

@ -9,6 +9,7 @@ import net.zetetic.database.sqlcipher.SQLiteDatabase;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.util.CursorUtil;
import org.thoughtcrime.securesms.util.Util;
/**
* The default error handler wipes the file. This one instead prints some diagnostics and then crashes so the original corrupt file isn't lost.
@ -24,30 +25,60 @@ public final class SqlCipherErrorHandler implements DatabaseErrorHandler {
}
@Override
@SuppressWarnings("ConstantConditions")
public void onCorruption(SQLiteDatabase db) {
Log.e(TAG, "Database '" + databaseName + "' corrupted! Going to try to run some diagnostics.");
StringBuilder output = new StringBuilder();
Log.w(TAG, " ===== PRAGMA integrity_check =====");
output.append("Database '").append(databaseName).append("' corrupted! Going to try to run some diagnostics.").append("\n");
boolean pragma1Passes = false;
boolean pragma2Passes = true;
output.append(" ===== PRAGMA integrity_check =====").append("\n");
try (Cursor cursor = db.rawQuery("PRAGMA integrity_check", null)) {
while (cursor.moveToNext()) {
Log.w(TAG, CursorUtil.readRowAsString(cursor));
String row = CursorUtil.readRowAsString(cursor);
output.append(row).append("\n");
if (row.toLowerCase().contains("ok")) {
pragma1Passes = true;
}
}
} catch (Throwable t) {
Log.e(TAG, "Failed to do integrity_check!", t);
output.append("Failed to do integrity_check!").append("\n")
.append(Util.convertThrowableToString(t));
}
Log.w(TAG, "===== PRAGMA cipher_integrity_check =====");
output.append("\n").append("===== PRAGMA cipher_integrity_check =====").append("\n");
try (Cursor cursor = db.rawQuery("PRAGMA cipher_integrity_check", null)) {
while (cursor.moveToNext()) {
Log.w(TAG, CursorUtil.readRowAsString(cursor));
output.append(CursorUtil.readRowAsString(cursor)).append("\n");
pragma2Passes = false;
}
} catch (Throwable t) {
Log.e(TAG, "Failed to do cipher_integrity_check!", t);
output.append("Failed to do cipher_integrity_check!").append("\n")
.append(Util.convertThrowableToString(t));
}
throw new DatabaseCorruptedError();
Log.e(TAG, output.toString());
if (pragma1Passes && pragma2Passes) {
throw new DatabaseCorruptedError_BothChecksPass();
} else if (!pragma1Passes && pragma2Passes) {
throw new DatabaseCorruptedError_NormalCheckFailsCipherCheckPasses();
} else if (pragma1Passes && !pragma2Passes) {
throw new DatabaseCorruptedError_NormalCheckPassesCipherCheckFails();
} else {
throw new DatabaseCorruptedError_BothChecksFail();
}
}
public static final class DatabaseCorruptedError extends Error {
public static final class DatabaseCorruptedError_BothChecksPass extends Error {
}
public static final class DatabaseCorruptedError_BothChecksFail extends Error {
}
public static final class DatabaseCorruptedError_NormalCheckFailsCipherCheckPasses extends Error {
}
public static final class DatabaseCorruptedError_NormalCheckPassesCipherCheckFails extends Error {
}
}

Wyświetl plik

@ -54,6 +54,7 @@ import org.whispersystems.libsignal.util.guava.Optional;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.ArrayList;
@ -535,4 +536,10 @@ public class Util {
return primary;
}
public static @NonNull String convertThrowableToString(@NonNull Throwable throwable) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
throwable.printStackTrace(new PrintStream(outputStream));
return outputStream.toString();
}
}