From a570e0b43ef0c7b73356fc855fa602e78ea8fea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A8chico10117=C2=A8?= Date: Fri, 7 Aug 2026 16:00:30 -0600 Subject: [PATCH] fix(comments): preserve emoji text fallback Keep attachment text intact when a channel emoji image comes from an unsupported host instead of rewriting it to an invalid /ggpht path. Add regression coverage for the fallback. --- spec/invidious/videos/description_spec.cr | 24 +++++++++++++++++++ src/invidious/videos/description.cr | 28 +++++++++++++++++------ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/spec/invidious/videos/description_spec.cr b/spec/invidious/videos/description_spec.cr index 3fca140d2..b1e2218f9 100644 --- a/spec/invidious/videos/description_spec.cr +++ b/spec/invidious/videos/description_spec.cr @@ -72,4 +72,28 @@ Spectator.describe "parse_description" do expect(parse_description(description, "video-id")).to eq("hello:custom-emoji:") end + + it "preserves attachment text when the image host is unsupported" do + description = JSON.parse(<<-JSON) + { + "content": "one:custom-emoji:two", + "attachmentRuns": [{ + "startIndex": 3, + "length": 14, + "element": { + "type": { + "imageType": { + "image": { + "sources": [{"url": "https://example.com/custom.png", "width": 16, "height": 16}] + } + } + } + }, + "properties": {"accessibilityProperties": {"label": "custom-emoji"}} + }] + } + JSON + + expect(parse_description(description, "video-id")).to eq("one:custom-emoji:two") + end end diff --git a/src/invidious/videos/description.cr b/src/invidious/videos/description.cr index eb8638530..44979b468 100644 --- a/src/invidious/videos/description.cr +++ b/src/invidious/videos/description.cr @@ -52,26 +52,40 @@ private def skip_string(iter : Iterator, count : Int) : Int skipped end -private def parse_attachment_run(attachment) : String? - image_source = attachment.dig?("element", "type", "imageType", "image", "sources", 0) - return if image_source.nil? +private def image_source(url : String) : String? + uri = URI.parse(url) - url = image_source["url"]?.try &.as_s? + case uri.host + when "yt3.ggpht.com", "lh3.googleusercontent.com" + "/ggpht#{HTML.escape(uri.request_target)}" + end +rescue + nil +end + +private def parse_attachment_run(attachment) : String? + source = attachment.dig?("element", "type", "imageType", "image", "sources", 0) + return if source.nil? + + url = source["url"]?.try &.as_s? return if url.nil? + src = image_source(url) + return if src.nil? + label = attachment.dig?("properties", "accessibilityProperties", "label").try &.as_s? || "" escaped_label = HTML.escape(label) String.build do |str| str << %(