From a524e1a030aa66b6e80846f6216f19f72bf8df22 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Wed, 17 Jun 2026 10:23:25 -0400 Subject: [PATCH] md_html: Escape raw HTML in image alt attribute The image label is rendered into the alt="..." attribute opened by render_open_img_span(). enter_span_callback() already suppresses nested span tags while inside an image, but text_callback() still emitted MD_TEXT_HTML verbatim, so a raw HTML span in the label broke out of the attribute. For example ![](/url) rendered as <x title="> where onerror becomes a live attribute on the generated img element. Route MD_TEXT_HTML through render_html_escaped() when image_nesting_level is greater than zero, matching the documented intent that only plain text falls into alt (and cmark-gfm, which escapes raw HTML in the same context). Behaviour outside image labels is unchanged. --- src/md4c-html.c | 11 ++++++++++- test/regressions.txt | 13 +++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/md4c-html.c b/src/md4c-html.c index 9662cfd2..590078d8 100644 --- a/src/md4c-html.c +++ b/src/md4c-html.c @@ -577,7 +577,16 @@ text_callback(MD_TEXTTYPE type, const MD_CHAR* text, MD_SIZE size, void* userdat : " ")); break; case MD_TEXT_SOFTBR: RENDER_VERBATIM(r, (r->image_nesting_level == 0 ? "\n" : " ")); break; - case MD_TEXT_HTML: render_verbatim(r, text, size); break; + case MD_TEXT_HTML: /* When inside a Markdown image label, the text falls into + * the alt="..." attribute opened by render_open_img_span(). + * Raw HTML must be escaped there, exactly like normal text, + * otherwise it breaks out of the attribute. Compare the + * image_nesting_level handling in enter_span_callback(). */ + if(r->image_nesting_level == 0) + render_verbatim(r, text, size); + else + render_html_escaped(r, text, size); + break; case MD_TEXT_ENTITY: render_entity(r, text, size, render_html_escaped); break; default: render_html_escaped(r, text, size); break; } diff --git a/test/regressions.txt b/test/regressions.txt index 555a04ab..8bf75563 100644 --- a/test/regressions.txt +++ b/test/regressions.txt @@ -1026,4 +1026,17 @@ http://example.com> .

< http://example.com>

+```````````````````````````````` + + +## Raw HTML in an image label must not break out of the alt attribute + +The image label is rendered into the `alt="..."` attribute, so any raw +HTML span in it has to be escaped like normal text instead of being +emitted verbatim. + +```````````````````````````````` example +![](/url) +. +

<x title=" y" onerror="alert(1)">

```````````````````````````````` \ No newline at end of file