Switch to parameterized statements for backup

Fixes #7507
This commit is contained in:
Moxie Marlinspike 2018-03-13 09:27:58 -07:00
parent 52ca295131
commit 64afce5f66
4 changed files with 1228 additions and 29 deletions

View File

@ -10,7 +10,16 @@ option java_package = "org.thoughtcrime.securesms.backup";
option java_outer_classname = "BackupProtos";
message SqlStatement {
optional string statement = 1;
message SqlParameter {
optional string stringParamter = 1;
optional uint64 integerParameter = 2;
optional double doubleParameter = 3;
optional bytes blobParameter = 4;
optional bool nullparameter = 5;
}
optional string statement = 1;
repeated SqlParameter parameters = 2;
}
message SharedPreference {

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,6 @@ import org.thoughtcrime.securesms.database.SessionDatabase;
import org.thoughtcrime.securesms.database.SignedPreKeyDatabase;
import org.thoughtcrime.securesms.database.SmsDatabase;
import org.thoughtcrime.securesms.util.Conversions;
import org.thoughtcrime.securesms.util.Hex;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libsignal.kdf.HKDFv3;
import org.whispersystems.libsignal.util.ByteUtil;
@ -136,25 +135,24 @@ public class FullBackupExporter extends FullBackupBase {
EventBus.getDefault().post(new BackupEvent(BackupEvent.Type.PROGRESS, ++count));
if (predicate == null || predicate.test(cursor)) {
StringBuilder statement = new StringBuilder(template);
StringBuilder statement = new StringBuilder(template);
BackupProtos.SqlStatement.Builder statementBuilder = BackupProtos.SqlStatement.newBuilder();
statement.append('(');
for (int i=0;i<cursor.getColumnCount();i++) {
statement.append('?');
if (cursor.getType(i) == Cursor.FIELD_TYPE_STRING) {
statement.append('\'');
statement.append(cursor.getString(i).replace("'", "''"));
statement.append('\'');
statementBuilder.addParameters(BackupProtos.SqlStatement.SqlParameter.newBuilder().setStringParamter(cursor.getString(i)));
} else if (cursor.getType(i) == Cursor.FIELD_TYPE_FLOAT) {
statement.append(cursor.getFloat(i));
statementBuilder.addParameters(BackupProtos.SqlStatement.SqlParameter.newBuilder().setDoubleParameter(cursor.getDouble(i)));
} else if (cursor.getType(i) == Cursor.FIELD_TYPE_INTEGER) {
statement.append(cursor.getLong(i));
statementBuilder.addParameters(BackupProtos.SqlStatement.SqlParameter.newBuilder().setIntegerParameter(cursor.getLong(i)));
} else if (cursor.getType(i) == Cursor.FIELD_TYPE_BLOB) {
statement.append("x'");
statement.append(Hex.toStringCondensed(cursor.getBlob(i)));
statement.append('\'');
statementBuilder.addParameters(BackupProtos.SqlStatement.SqlParameter.newBuilder().setBlobParameter(ByteString.copyFrom(cursor.getBlob(i))));
} else if (cursor.getType(i) == Cursor.FIELD_TYPE_NULL) {
statement.append("NULL");
statementBuilder.addParameters(BackupProtos.SqlStatement.SqlParameter.newBuilder().setNullparameter(true));
} else {
throw new AssertionError("unknown type?" + cursor.getType(i));
}
@ -166,7 +164,7 @@ public class FullBackupExporter extends FullBackupBase {
statement.append(')');
outputStream.write(BackupProtos.SqlStatement.newBuilder().setStatement(statement.toString()).build());
outputStream.write(statementBuilder.setStatement(statement.toString()).build());
if (postProcess != null) postProcess.accept(cursor);
}

View File

@ -6,8 +6,12 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.support.annotation.NonNull;
import android.util.Log;
import android.util.Pair;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import net.sqlcipher.database.SQLiteDatabase;
import org.greenrobot.eventbus.EventBus;
@ -33,6 +37,8 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
import java.util.List;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
@ -82,7 +88,18 @@ public class FullBackupImporter extends FullBackupBase {
}
private static void processStatement(@NonNull SQLiteDatabase db, SqlStatement statement) {
db.execSQL(statement.getStatement());
List<Object> parameters = new LinkedList<>();
for (SqlStatement.SqlParameter parameter : statement.getParametersList()) {
if (parameter.hasStringParamter()) parameters.add(parameter.getStringParamter());
else if (parameter.hasDoubleParameter()) parameters.add(parameter.getDoubleParameter());
else if (parameter.hasIntegerParameter()) parameters.add(parameter.getIntegerParameter());
else if (parameter.hasBlobParameter()) parameters.add(parameter.getBlobParameter().toByteArray());
else if (parameter.hasNullparameter()) parameters.add(null);
}
if (parameters.size() > 0) db.execSQL(statement.getStatement(), parameters.toArray());
else db.execSQL(statement.getStatement());
}
private static void processAttachment(@NonNull Context context, @NonNull AttachmentSecret attachmentSecret, @NonNull SQLiteDatabase db, @NonNull Attachment attachment, BackupRecordInputStream inputStream)