diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java index 54809068a..ab1a5a10c 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsExportService.java @@ -76,7 +76,10 @@ public class SubscriptionsExportService extends BaseImportExportService { try { outFile = new StoredFileHelper(this, path, "application/json"); - outputStream = new SharpOutputStream(outFile.getStream()); + // truncate the file before writing to it, otherwise if the new content is smaller than + // the previous file size, the file will retain part of the previous content and be + // corrupted + outputStream = new SharpOutputStream(outFile.openAndTruncateStream()); } catch (final IOException e) { handleError(e); return START_NOT_STICKY; diff --git a/app/src/main/java/org/schabi/newpipe/settings/export/ImportExportManager.kt b/app/src/main/java/org/schabi/newpipe/settings/export/ImportExportManager.kt index 93c1bfb81..36e0b9ce1 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/export/ImportExportManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/export/ImportExportManager.kt @@ -24,8 +24,9 @@ class ImportExportManager(private val fileLocator: BackupFileLocator) { */ @Throws(Exception::class) fun exportDatabase(preferences: SharedPreferences, file: StoredFileHelper) { - file.create() - ZipOutputStream(SharpOutputStream(file.stream).buffered()).use { outZip -> + // truncate the file before writing to it, otherwise if the new content is smaller than the + // previous file size, the file will retain part of the previous content and be corrupted + ZipOutputStream(SharpOutputStream(file.openAndTruncateStream()).buffered()).use { outZip -> // add the database ZipHelper.addFileToZip( outZip, diff --git a/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java b/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java index 5404426c4..1e2c178bf 100644 --- a/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java +++ b/app/src/main/java/org/schabi/newpipe/streams/io/StoredFileHelper.java @@ -189,6 +189,19 @@ public class StoredFileHelper implements Serializable { } } + public SharpStream openAndTruncateStream() throws IOException { + final SharpStream sharpStream = getStream(); + try { + sharpStream.setLength(0); + } catch (final Throwable e) { + // we can't use try-with-resources here, since we only want to close the stream if an + // exception occurs, but leave it open if everything goes well + sharpStream.close(); + throw e; + } + return sharpStream; + } + /** * Indicates whether it's using the {@code java.io} API. * diff --git a/app/src/test/java/org/schabi/newpipe/settings/ImportExportManagerTest.kt b/app/src/test/java/org/schabi/newpipe/settings/ImportExportManagerTest.kt index a524f64f3..5b8023561 100644 --- a/app/src/test/java/org/schabi/newpipe/settings/ImportExportManagerTest.kt +++ b/app/src/test/java/org/schabi/newpipe/settings/ImportExportManagerTest.kt @@ -55,7 +55,7 @@ class ImportExportManagerTest { `when`(sharedPreferences.all).thenReturn(expectedPreferences) val output = File.createTempFile("newpipe_", "") - `when`(storedFileHelper.stream).thenReturn(FileStream(output)) + `when`(storedFileHelper.openAndTruncateStream()).thenReturn(FileStream(output)) ImportExportManager(fileLocator).exportDatabase(sharedPreferences, storedFileHelper) val zipFile = ZipFile(output)