Check backup format before restoring

master
Koitharu 2 years ago
parent b33c93290b
commit 905f565766
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -6,12 +6,14 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runInterruptible import kotlinx.coroutines.runInterruptible
import okio.Closeable import okio.Closeable
import org.json.JSONArray import org.json.JSONArray
import org.koitharu.kotatsu.core.exceptions.BadBackupFormatException
import org.koitharu.kotatsu.core.util.ext.processLifecycleScope import org.koitharu.kotatsu.core.util.ext.processLifecycleScope
import java.io.File import java.io.File
import java.util.EnumSet import java.util.EnumSet
import java.util.zip.ZipException
import java.util.zip.ZipFile import java.util.zip.ZipFile
class BackupZipInput(val file: File) : Closeable { class BackupZipInput private constructor(val file: File) : Closeable {
private val zipFile = ZipFile(file) private val zipFile = ZipFile(file)
@ -41,4 +43,17 @@ class BackupZipInput(val file: File) : Closeable {
} }
} }
} }
companion object {
fun from(file: File): BackupZipInput = try {
val res = BackupZipInput(file)
if (res.zipFile.getEntry("index") == null) {
throw BadBackupFormatException(null)
}
res
} catch (e: ZipException) {
throw BadBackupFormatException(e)
}
}
} }

@ -0,0 +1,5 @@
package org.koitharu.kotatsu.core.exceptions
import java.io.IOException
class BadBackupFormatException(cause: Throwable?) : IOException(cause)

@ -10,6 +10,7 @@ import okio.IOException
import org.acra.ktx.sendWithAcra import org.acra.ktx.sendWithAcra
import org.jsoup.HttpStatusException import org.jsoup.HttpStatusException
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.exceptions.BadBackupFormatException
import org.koitharu.kotatsu.core.exceptions.CaughtException import org.koitharu.kotatsu.core.exceptions.CaughtException
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
import org.koitharu.kotatsu.core.exceptions.EmptyHistoryException import org.koitharu.kotatsu.core.exceptions.EmptyHistoryException
@ -43,6 +44,7 @@ fun Throwable.getDisplayMessage(resources: Resources): String = when (this) {
is TooManyRequestExceptions -> resources.getString(R.string.too_many_requests_message) is TooManyRequestExceptions -> resources.getString(R.string.too_many_requests_message)
is UnsupportedFileException -> resources.getString(R.string.text_file_not_supported) is UnsupportedFileException -> resources.getString(R.string.text_file_not_supported)
is BadBackupFormatException -> resources.getString(R.string.unsupported_backup_message)
is FileNotFoundException -> resources.getString(R.string.file_not_found) is FileNotFoundException -> resources.getString(R.string.file_not_found)
is AccessDeniedException -> resources.getString(R.string.no_access_to_file) is AccessDeniedException -> resources.getString(R.string.no_access_to_file)
is EmptyHistoryException -> resources.getString(R.string.history_is_empty) is EmptyHistoryException -> resources.getString(R.string.history_is_empty)

@ -13,7 +13,9 @@ import org.koitharu.kotatsu.core.backup.BackupRepository
import org.koitharu.kotatsu.core.backup.BackupZipInput import org.koitharu.kotatsu.core.backup.BackupZipInput
import org.koitharu.kotatsu.core.backup.BackupZipOutput import org.koitharu.kotatsu.core.backup.BackupZipOutput
import org.koitharu.kotatsu.core.db.MangaDatabase import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.core.exceptions.BadBackupFormatException
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import java.io.File import java.io.File
import java.io.FileDescriptor import java.io.FileDescriptor
import java.io.FileInputStream import java.io.FileInputStream
@ -88,7 +90,12 @@ class AppBackupAgent : BackupAgent() {
input.copyLimitedTo(output, size) input.copyLimitedTo(output, size)
} }
} }
val backup = BackupZipInput(tempFile) val backup = try {
BackupZipInput.from(tempFile)
} catch (e: BadBackupFormatException) {
tempFile.delete()
throw e
}
try { try {
runBlocking { runBlocking {
backup.getEntry(BackupEntry.Name.HISTORY)?.let { repository.restoreHistory(it) } backup.getEntry(BackupEntry.Name.HISTORY)?.let { repository.restoreHistory(it) }

@ -1,6 +1,8 @@
package org.koitharu.kotatsu.settings.backup package org.koitharu.kotatsu.settings.backup
import android.content.ContentResolver
import android.content.Context import android.content.Context
import android.net.Uri
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
@ -11,6 +13,8 @@ import org.koitharu.kotatsu.core.backup.BackupEntry
import org.koitharu.kotatsu.core.backup.BackupRepository import org.koitharu.kotatsu.core.backup.BackupRepository
import org.koitharu.kotatsu.core.backup.BackupZipInput import org.koitharu.kotatsu.core.backup.BackupZipInput
import org.koitharu.kotatsu.core.backup.CompositeResult import org.koitharu.kotatsu.core.backup.CompositeResult
import org.koitharu.kotatsu.core.exceptions.BadBackupFormatException
import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException
import org.koitharu.kotatsu.core.ui.BaseViewModel import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
import org.koitharu.kotatsu.core.util.ext.call import org.koitharu.kotatsu.core.util.ext.call
@ -41,7 +45,7 @@ class RestoreViewModel @Inject constructor(
input.copyTo(output) input.copyTo(output)
} }
} }
BackupZipInput(tempFile) BackupZipInput.from(tempFile)
} }
} }

@ -641,4 +641,5 @@
<string name="show_pages_thumbs">Show pages thumbnails</string> <string name="show_pages_thumbs">Show pages thumbnails</string>
<string name="show_pages_thumbs_summary">Enable the \"Pages\" tab on the details screen</string> <string name="show_pages_thumbs_summary">Enable the \"Pages\" tab on the details screen</string>
<string name="error_no_data_received">No data was received from server</string> <string name="error_no_data_received">No data was received from server</string>
<string name="unsupported_backup_message">Please select a proper Kotatsu backup file</string>
</resources> </resources>

Loading…
Cancel
Save