Yomu Comics: Fix NullPointerException on encrypted payloads - #18483
Merged
AwkwardPeak7 merged 2 commits intoAug 19, 2026
Conversation
The site now ships its library, chapter and page payloads encrypted with CryptoJS AES, so the old plain-text lookups returned null. Decrypts them with lib:cryptoaes, reads the series page from the flight response and migrates the source to KeiSource.
AwkwardPeak7
requested changes
Aug 18, 2026
| abstract class YomuComics : KeiSource() { | ||
|
|
||
| override val supportsLatest = true | ||
| private val siteHost: String by lazy { baseUrl.toHttpUrl().host } |
Contributor
There was a problem hiding this comment.
Suggested change
| private val siteHost: String by lazy { baseUrl.toHttpUrl().host } | |
| private val siteHost: String get() = baseUrl.toHttpUrl().host |
also inline it
|
|
||
| override fun headersBuilder() = super.headersBuilder() | ||
| .add("Referer", "$baseUrl/") | ||
| private val rscHeaders: Headers by lazy { headers.newBuilder().set("RSC", "1").build() } |
Contributor
There was a problem hiding this comment.
Suggested change
| private val rscHeaders: Headers by lazy { headers.newBuilder().set("RSC", "1").build() } | |
| private val rscHeaders: Headers get() = headersBuilder().set("RSC", "1").build() |
| name = title?.takeIf(String::isNotBlank) ?: "Capítulo $label" | ||
| chapter_number = number.toFloat() | ||
| date_upload = parseChapterDate(releaseAt, releaseDate) | ||
| date_upload = releaseAt?.let(Instant::parseOrNull)?.toEpochMilliseconds() ?: releaseDate.toTimestamp() |
Contributor
There was a problem hiding this comment.
use the date utils
Instant.tryParse
DATE_FORMAT.tryParseDate
| name = title?.takeUnless { it.isBlank() } ?: "Capítulo $chapterNumberLabel" | ||
| fun toSChapter(mangaSlug: String) = SChapter.create().apply { | ||
| val label = number.formatted() | ||
| url = "/ler/$mangaSlug/$label?chapterId=$id" |
Contributor
There was a problem hiding this comment.
perhaps save just the id in url and save rest of required data in memo
Use the date utils, store the chapter id in the url with the rest in memo, and turn siteHost/rscHeaders into getters.
AwkwardPeak7
approved these changes
Aug 19, 2026
This was referenced Aug 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #17914
The site now ships its library, chapter list and page payloads encrypted with CryptoJS AES. The old code looked for
capitulos_lista/imagens_listain plain text and then didmatches[selectRealArray(chapterArrays)!!], so the lookup returned null and the!!threw the reportedNullPointerException.Payloads are now decrypted with
lib:cryptoaesusing the passphrase the site derives in its bundle. On/api/librarythe field holding the list is renamed often (garimpo,catalogo, ...), so the encrypted value is located by itsU2FsdGVkX1prefix instead of by name.The series page is now read from the flight response (
RSC: 1) rather than the HTML. In the HTML the ByteText chunk is split acrossself.__next_f.pushscript tags, which truncates the encrypted payload and yields an empty chapter list; the RSC body is a single stream. It is also far smaller: a large series is ~1 MB as RSC against ~16 MB as HTML.Other changes:
KeiSource.Utils.kt. The "pick the real array" heuristics are no longer needed now that the payload is unambiguous.cdn.yomu.com.br./api/genresinstead of being hardcoded.contentWarningset toMIXED(the catalogue mixes regular and adult types), replacing the previous "or MIXED, please confirm" placeholder.Tested on an emulator with Mihon: popular, latest, text search, URL search, filters, details, chapter list and reading pages.
Checklist:
versionCodevalue inbuild.gradle.ktsbaseVersionCodeinbuild.gradle.kts(if updated multisrc theme code)contentWarningconfiguration inbuild.gradle.ktsappropriatelyidif a source's name or language were changedweb_hi_res_512.pngwhen adding a new extension