From aab1b4980cb099674d631b0e7f3d135f8bde751d Mon Sep 17 00:00:00 2001 From: ace Date: Wed, 19 Nov 2025 18:59:32 +0530 Subject: [PATCH 1/2] fix: feed character decoding issue --- .../java/me/ash/reader/infrastructure/rss/RssHelper.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt b/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt index 2d23dc9fc..19b73745a 100644 --- a/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt +++ b/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt @@ -49,9 +49,9 @@ constructor( suspend fun searchFeed(feedLink: String): SyndFeed { return withContext(ioDispatcher) { val response = response(okHttpClient, feedLink) - val contentType = response.header("Content-Type") + // val contentType = response.header("Content-Type") response.body.byteStream().use { inputStream -> - SyndFeedInput().build(XmlReader(inputStream, contentType)).also { + SyndFeedInput().build(XmlReader(inputStream, Charsets.UTF_8.name())).also { it.icon = SyndImageImpl() it.icon.link = queryRssIconLink(feedLink) it.icon.url = it.icon.link @@ -119,11 +119,11 @@ constructor( try { val accountId = context.currentAccountId val response = response(okHttpClient, feed.url) - val contentType = response.header("Content-Type") + // val contentType = response.header("Content-Type") response.body.byteStream().use { inputStream -> SyndFeedInput() .apply { isPreserveWireFeed = true } - .build(XmlReader(inputStream, contentType)) + .build(XmlReader(inputStream, Charsets.UTF_8.name())) .entries .asSequence() .takeWhile { latestLink == null || latestLink != it.link } From d2f4f1f1974ee9e6dbfe021f65c04f3006251bc5 Mon Sep 17 00:00:00 2001 From: ace Date: Sun, 23 Nov 2025 13:33:29 +0530 Subject: [PATCH 2/2] fix: prefer HTTP header charset, fallback to UTF-8 for missing charset --- .../reader/infrastructure/rss/RssHelper.kt | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt b/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt index 19b73745a..a465698b6 100644 --- a/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt +++ b/app/src/main/java/me/ash/reader/infrastructure/rss/RssHelper.kt @@ -49,9 +49,16 @@ constructor( suspend fun searchFeed(feedLink: String): SyndFeed { return withContext(ioDispatcher) { val response = response(okHttpClient, feedLink) - // val contentType = response.header("Content-Type") + val contentType = response.header("Content-Type") + val httpContentType = + contentType?.let { + if (it.contains("charset=", ignoreCase = true)) it + else "$it; charset=UTF-8" + } ?: "text/xml; charset=UTF-8" + + response.body.byteStream().use { inputStream -> - SyndFeedInput().build(XmlReader(inputStream, Charsets.UTF_8.name())).also { + SyndFeedInput().build(XmlReader(inputStream, httpContentType)).also { it.icon = SyndImageImpl() it.icon.link = queryRssIconLink(feedLink) it.icon.url = it.icon.link @@ -119,11 +126,18 @@ constructor( try { val accountId = context.currentAccountId val response = response(okHttpClient, feed.url) - // val contentType = response.header("Content-Type") + val contentType = response.header("Content-Type") + + val httpContentType = + contentType?.let { + if (it.contains("charset=", ignoreCase = true)) it + else "$it; charset=UTF-8" + } ?: "text/xml; charset=UTF-8" + response.body.byteStream().use { inputStream -> SyndFeedInput() .apply { isPreserveWireFeed = true } - .build(XmlReader(inputStream, Charsets.UTF_8.name())) + .build(XmlReader(inputStream, httpContentType)) .entries .asSequence() .takeWhile { latestLink == null || latestLink != it.link }