From c892c793a82c0349a3001954fd3a4fda9fece0dd Mon Sep 17 00:00:00 2001 From: beerpsi <92439990+beerpiss@users.noreply.github.com> Date: Thu, 26 Jan 2023 21:14:18 +0700 Subject: [PATCH] [BackupRestorer] Handle uncompressed backups (#8988) [Backups] Handle uncompressed backups --- .../data/backup/BackupFileValidator.kt | 12 ++----- .../tachiyomi/data/backup/BackupRestorer.kt | 7 ++-- .../eu/kanade/tachiyomi/util/BackupUtil.kt | 32 +++++++++++++++++++ 3 files changed, 36 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/util/BackupUtil.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupFileValidator.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupFileValidator.kt index 1181436224..263acdf39e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupFileValidator.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupFileValidator.kt @@ -3,12 +3,9 @@ package eu.kanade.tachiyomi.data.backup import android.content.Context import android.net.Uri import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.backup.models.BackupSerializer import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.source.SourceManager -import okio.buffer -import okio.gzip -import okio.source +import eu.kanade.tachiyomi.util.BackupUtil import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get @@ -24,13 +21,8 @@ class BackupFileValidator( * @return List of missing sources or missing trackers. */ fun validate(context: Context, uri: Uri): Results { - val backupManager = BackupManager(context) - val backup = try { - val backupString = - context.contentResolver.openInputStream(uri)!!.source().gzip().buffer() - .use { it.readByteArray() } - backupManager.parser.decodeFromByteArray(BackupSerializer, backupString) + BackupUtil.decodeBackup(context, uri) } catch (e: Exception) { throw IllegalStateException(e) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt index 1ec8572425..e515bf99fa 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestorer.kt @@ -6,15 +6,13 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.backup.models.BackupCategory import eu.kanade.tachiyomi.data.backup.models.BackupHistory import eu.kanade.tachiyomi.data.backup.models.BackupManga -import eu.kanade.tachiyomi.data.backup.models.BackupSerializer import eu.kanade.tachiyomi.data.backup.models.BackupSource import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Track +import eu.kanade.tachiyomi.util.BackupUtil import eu.kanade.tachiyomi.util.system.createFileInCacheDir import kotlinx.coroutines.Job -import okio.buffer -import okio.gzip import okio.source import java.io.File import java.text.SimpleDateFormat @@ -79,8 +77,7 @@ class BackupRestorer( @Suppress("BlockingMethodInNonBlockingContext") private suspend fun performRestore(uri: Uri): Boolean { - val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() } - val backup = backupManager.parser.decodeFromByteArray(BackupSerializer, backupString) + val backup = BackupUtil.decodeBackup(context, uri) restoreAmount = backup.backupManga.size + 1 // +1 for categories diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/BackupUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/BackupUtil.kt new file mode 100644 index 0000000000..0abd22f13a --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/util/BackupUtil.kt @@ -0,0 +1,32 @@ +package eu.kanade.tachiyomi.util + +import android.content.Context +import android.net.Uri +import eu.kanade.tachiyomi.data.backup.BackupManager +import eu.kanade.tachiyomi.data.backup.models.Backup +import eu.kanade.tachiyomi.data.backup.models.BackupSerializer +import okio.buffer +import okio.gzip +import okio.source + +object BackupUtil { + /** + * Decode a potentially-gzipped backup. + */ + fun decodeBackup(context: Context, uri: Uri): Backup { + val backupManager = BackupManager(context) + + val backupStringSource = context.contentResolver.openInputStream(uri)!!.source().buffer() + + val peeked = backupStringSource.peek() + peeked.require(2) + val id1id2 = peeked.readShort() + val backupString = if (id1id2.toInt() == 0x1f8b) { // 0x1f8b is gzip magic bytes + backupStringSource.gzip().buffer() + } else { + backupStringSource + }.use { it.readByteArray() } + + return backupManager.parser.decodeFromByteArray(BackupSerializer, backupString) + } +}