Add check to avoid TransactionTooLargeException
This commit is contained in:
@@ -4,7 +4,7 @@ import android.os.Parcel
|
|||||||
import androidx.core.os.ParcelCompat
|
import androidx.core.os.ParcelCompat
|
||||||
import org.koitharu.kotatsu.parsers.model.*
|
import org.koitharu.kotatsu.parsers.model.*
|
||||||
|
|
||||||
fun Manga.writeToParcel(out: Parcel, flags: Int) {
|
fun Manga.writeToParcel(out: Parcel, flags: Int, withChapters: Boolean) {
|
||||||
out.writeLong(id)
|
out.writeLong(id)
|
||||||
out.writeString(title)
|
out.writeString(title)
|
||||||
out.writeString(altTitle)
|
out.writeString(altTitle)
|
||||||
@@ -18,7 +18,11 @@ fun Manga.writeToParcel(out: Parcel, flags: Int) {
|
|||||||
out.writeParcelable(ParcelableMangaTags(tags), flags)
|
out.writeParcelable(ParcelableMangaTags(tags), flags)
|
||||||
out.writeSerializable(state)
|
out.writeSerializable(state)
|
||||||
out.writeString(author)
|
out.writeString(author)
|
||||||
out.writeParcelable(chapters?.let(::ParcelableMangaChapters), flags)
|
if (withChapters) {
|
||||||
|
out.writeParcelable(chapters?.let(::ParcelableMangaChapters), flags)
|
||||||
|
} else {
|
||||||
|
out.writeString(null)
|
||||||
|
}
|
||||||
out.writeSerializable(source)
|
out.writeSerializable(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,24 +2,34 @@ package org.koitharu.kotatsu.core.model.parcelable
|
|||||||
|
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.util.Log
|
|
||||||
import org.koitharu.kotatsu.BuildConfig
|
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.Manga
|
||||||
|
|
||||||
|
// Limits to avoid TransactionTooLargeException
|
||||||
|
private const val MAX_SAFE_SIZE = 1024 * 512 // Assume that 512 kb is safe parcel size
|
||||||
|
private const val MAX_SAFE_CHAPTERS_COUNT = 40 // this is 100% safe
|
||||||
|
|
||||||
class ParcelableManga(
|
class ParcelableManga(
|
||||||
val manga: Manga,
|
val manga: Manga,
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
|
||||||
constructor(parcel: Parcel) : this(parcel.readManga())
|
constructor(parcel: Parcel) : this(parcel.readManga())
|
||||||
|
|
||||||
init {
|
|
||||||
if (BuildConfig.DEBUG && manga.chapters != null) {
|
|
||||||
Log.w("ParcelableManga", "Passing manga with chapters as Parcelable is dangerous!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||||
manga.writeToParcel(parcel, flags)
|
val chapters = manga.chapters
|
||||||
|
if (chapters == null || chapters.size <= MAX_SAFE_CHAPTERS_COUNT) {
|
||||||
|
// fast path
|
||||||
|
manga.writeToParcel(parcel, flags, withChapters = true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val tempParcel = Parcel.obtain()
|
||||||
|
manga.writeToParcel(tempParcel, flags, withChapters = true)
|
||||||
|
val size = tempParcel.dataSize()
|
||||||
|
if (size < MAX_SAFE_SIZE) {
|
||||||
|
parcel.appendFrom(tempParcel, 0, size)
|
||||||
|
} else {
|
||||||
|
manga.writeToParcel(parcel, flags, withChapters = false)
|
||||||
|
}
|
||||||
|
tempParcel.recycle()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun describeContents(): Int {
|
override fun describeContents(): Int {
|
||||||
|
|||||||
Reference in New Issue
Block a user