diff --git a/web/src/postprocess_content.ts b/web/src/postprocess_content.ts index b5c7edaf7f..3309b71b4d 100644 --- a/web/src/postprocess_content.ts +++ b/web/src/postprocess_content.ts @@ -112,7 +112,17 @@ export function postprocess_content(html: string): string { // `/user_uploads/thumbnail`, even though that's what the // server writes in the markup, because Firefox will have // already prepended the origin to the source of an image. - const image_url = new URL(inline_img.src, window.location.origin); + let image_url; + try { + image_url = new URL(inline_img.src, window.location.origin); + } catch { + // If the image source URL can't be parsed, likely due to + // some historical bug in the Markdown processor, just + // drop the invalid image element. + inline_img.closest("div.message_inline_image")!.remove(); + continue; + } + if ( image_url.origin === window.location.origin && image_url.pathname.startsWith("/user_uploads/thumbnail/") diff --git a/web/tests/postprocess_content.test.cjs b/web/tests/postprocess_content.test.cjs index 9f4dd1a6be..21c0b2d45f 100644 --- a/web/tests/postprocess_content.test.cjs +++ b/web/tests/postprocess_content.test.cjs @@ -151,4 +151,18 @@ run_test("message_inline_animated_image_still", ({override}) => { "" + "", ); + + // Broken/invalid source URLs in image previews should be + // dropped. Inspired by a real message found in chat.zulip.org + // history. + assert.equal( + postprocess_content( + '
", + ), + "", + ); });