Merge pull request #3831 from ByteHamster/verify-database

Verify database version before import
This commit is contained in:
H. Lehmann 2020-02-05 00:51:26 +01:00 committed by GitHub
commit 3f85413b8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 29 deletions

View File

@ -216,8 +216,8 @@ public class ImportExportPreferencesFragment extends PreferenceFragmentCompat {
private void showExportErrorDialog(final Throwable error) {
progressDialog.dismiss();
final AlertDialog.Builder alert = new AlertDialog.Builder(getContext())
.setNeutralButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
final AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
alert.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
alert.setTitle(R.string.export_error_label);
alert.setMessage(error.getMessage());
alert.show();

View File

@ -1,6 +1,8 @@
package de.danoeh.antennapod.core.storage;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@ -14,21 +16,10 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.Arrays;
public class DatabaseExporter {
private static final String TAG = "DatabaseExporter";
private static final byte[] SQLITE3_MAGIC = "SQLite format 3\0".getBytes();
public static boolean validateDB(Uri inputUri, Context context) throws IOException {
try (InputStream inputStream = context.getContentResolver().openInputStream(inputUri)) {
byte[] magicBuf = new byte[SQLITE3_MAGIC.length];
if (inputStream.read(magicBuf) == magicBuf.length) {
return Arrays.equals(SQLITE3_MAGIC, magicBuf);
}
}
return false;
}
private static final String TEMP_DB_NAME = PodDBAdapter.DATABASE_NAME + "_tmp";
public static void exportToDocument(Uri uri, Context context) throws IOException {
ParcelFileDescriptor pfd = null;
@ -78,14 +69,21 @@ public class DatabaseExporter {
public static void importBackup(Uri inputUri, Context context) throws IOException {
InputStream inputStream = null;
try {
if (!validateDB(inputUri, context)) {
throw new IOException(context.getString(R.string.import_bad_file));
File tempDB = context.getDatabasePath(TEMP_DB_NAME);
inputStream = context.getContentResolver().openInputStream(inputUri);
FileUtils.copyInputStreamToFile(inputStream, tempDB);
SQLiteDatabase db = SQLiteDatabase.openDatabase(tempDB.getAbsolutePath(),
null, SQLiteDatabase.OPEN_READONLY);
if (db.getVersion() > PodDBAdapter.VERSION) {
throw new IOException(context.getString(R.string.import_no_downgrade));
}
db.close();
File currentDB = context.getDatabasePath(PodDBAdapter.DATABASE_NAME);
inputStream = context.getContentResolver().openInputStream(inputUri);
FileUtils.copyInputStreamToFile(inputStream, currentDB);
} catch (IOException e) {
currentDB.delete();
FileUtils.moveFile(tempDB, currentDB);
} catch (IOException | SQLiteException e) {
Log.e(TAG, Log.getStackTraceString(e));
throw e;
} finally {

View File

@ -48,6 +48,7 @@ public class PodDBAdapter {
private static final String TAG = "PodDBAdapter";
public static final String DATABASE_NAME = "Antennapod.db";
public static final int VERSION = 1090000;
/**
* Maximum number of arguments for IN-operator.
@ -1336,8 +1337,6 @@ public class PodDBAdapter {
* Helper class for opening the Antennapod database.
*/
private static class PodDBHelper extends SQLiteOpenHelper {
private static final int VERSION = 1090000;
/**
* Constructor.
*
@ -1345,8 +1344,7 @@ public class PodDBAdapter {
* @param name Name of the database
* @param factory to use for creating cursor objects
*/
public PodDBHelper(final Context context, final String name,
final CursorFactory factory) {
public PodDBHelper(final Context context, final String name, final CursorFactory factory) {
super(context, name, factory, VERSION, new PodDbErrorHandler());
}
@ -1369,10 +1367,8 @@ public class PodDBAdapter {
}
@Override
public void onUpgrade(final SQLiteDatabase db, final int oldVersion,
final int newVersion) {
Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to "
+ newVersion + ".");
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
Log.w("DBAdapter", "Upgrading from version " + oldVersion + " to " + newVersion + ".");
DBUpgrader.upgrade(db, oldVersion, newVersion);
}
}

View File

@ -572,6 +572,7 @@
<string name="opml_import_ask_read_permission">Access to external storage is required to read the OPML file</string>
<string name="import_select_file">Select file to import</string>
<string name="import_ok">Import successful.\n\nPlease press OK to restart AntennaPod</string>
<string name="import_no_downgrade">This database was exported with a newer version of AntennaPod. Your current installation does not yet know how to handle this file.</string>
<!-- Sleep timer -->
<string name="set_sleeptimer_label">Set sleep timer</string>
@ -768,7 +769,6 @@
<string name="cast_failed_to_play">Failed to start the playback of media</string>
<string name="cast_failed_to_stop">Failed to stop the playback of media</string>
<string name="cast_failed_to_pause">Failed to pause the playback of media</string>
<!--<string name="cast_failed_to_connect">Could not connect to the device</string>-->
<string name="cast_failed_setting_volume">Failed to set the volume</string>
<string name="cast_failed_no_connection">No connection to the cast device is present</string>
<string name="cast_failed_no_connection_trans">Connection to the cast device has been lost. Application is trying to re-establish the connection, if possible. Please wait for a few seconds and try again.</string>
@ -786,7 +786,6 @@
<string name="notification_channel_playing_description">Allows to control playback. This is the main notification you see while playing a podcast.</string>
<string name="notification_channel_error">Errors</string>
<string name="notification_channel_error_description">Shown if something went wrong, for example if download or gpodder sync fails.</string>
<string name="import_bad_file">Invalid/corrupt file</string>
<!-- Widget settings -->
<string name="widget_settings">Widget settings</string>