Improve error message if restoring from JSON file (#1056)
Some checks failed
CI / Build app (push) Has been cancelled

* Improve error message if restoring from JSON file

* Replace Exception with IOException

* Use more generic error message if protobuf fails

* fix lint
This commit is contained in:
Vetle Ledaal 2024-07-31 16:39:41 +02:00 committed by GitHub
parent 8160b47ff5
commit de8ef6dad7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 23 additions and 6 deletions

View file

@ -3,18 +3,21 @@ package eu.kanade.tachiyomi.data.backup
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import eu.kanade.tachiyomi.data.backup.models.Backup import eu.kanade.tachiyomi.data.backup.models.Backup
import kotlinx.serialization.SerializationException
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import okio.buffer import okio.buffer
import okio.gzip import okio.gzip
import okio.source import okio.source
import tachiyomi.core.common.i18n.stringResource
import tachiyomi.i18n.MR
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.IOException
class BackupDecoder( class BackupDecoder(
private val context: Context, private val context: Context,
private val parser: ProtoBuf = Injekt.get(), private val parser: ProtoBuf = Injekt.get(),
) { ) {
/** /**
* Decode a potentially-gzipped backup. * Decode a potentially-gzipped backup.
*/ */
@ -26,13 +29,25 @@ class BackupDecoder(
require(2) require(2)
} }
val id1id2 = peeked.readShort() val id1id2 = peeked.readShort()
val backupString = if (id1id2.toInt() == 0x1f8b) { // 0x1f8b is gzip magic bytes val backupString = when (id1id2.toInt()) {
source.gzip().buffer() 0x1f8b -> source.gzip().buffer() // 0x1f8b is gzip magic bytes
} else { MAGIC_JSON_SIGNATURE1, MAGIC_JSON_SIGNATURE2, MAGIC_JSON_SIGNATURE3 -> {
source throw IOException(context.stringResource(MR.strings.invalid_backup_file_json))
}
else -> source
}.use { it.readByteArray() } }.use { it.readByteArray() }
try {
parser.decodeFromByteArray(Backup.serializer(), backupString) parser.decodeFromByteArray(Backup.serializer(), backupString)
} catch (_: SerializationException) {
throw IOException(context.stringResource(MR.strings.invalid_backup_file_unknown))
} }
} }
} }
companion object {
private const val MAGIC_JSON_SIGNATURE1 = 0x7b7d // `{}`
private const val MAGIC_JSON_SIGNATURE2 = 0x7b22 // `{"`
private const val MAGIC_JSON_SIGNATURE3 = 0x7b0a // `{\n`
}
}

View file

@ -518,6 +518,8 @@
<string name="invalid_backup_file">Invalid backup file:</string> <string name="invalid_backup_file">Invalid backup file:</string>
<string name="invalid_backup_file_error">Full error:</string> <string name="invalid_backup_file_error">Full error:</string>
<string name="invalid_backup_file_missing_manga">Backup does not contain any library entries.</string> <string name="invalid_backup_file_missing_manga">Backup does not contain any library entries.</string>
<string name="invalid_backup_file_json">JSON backup not supported</string>
<string name="invalid_backup_file_unknown">Backup file is corrupted</string>
<string name="backup_restore_missing_sources">Missing sources:</string> <string name="backup_restore_missing_sources">Missing sources:</string>
<string name="backup_restore_missing_trackers">Trackers not logged into:</string> <string name="backup_restore_missing_trackers">Trackers not logged into:</string>
<string name="backup_restore_content_full">You may need to install any missing extensions and log in to tracking services afterwards to use them.</string> <string name="backup_restore_content_full">You may need to install any missing extensions and log in to tracking services afterwards to use them.</string>