Encoded exactly once, and quoted where a quote would end an attribute
The counterpart to encoding the whole input up front: nothing downstream may encode a second time, and the few places a value is interpolated into an attribute need the quote characters that the text path deliberately leaves alone.
The rule
- Text is encoded exactly once.
- A sequence the conversion itself wrote must not be encoded again: a
<in the markdown source appears in the output as<and never as&lt;. - A text node may keep literal quote characters, which are harmless there.
- A value interpolated into an attribute (a link target, an image source, an image alternative text) must have its quote characters escaped, so the value cannot end its own attribute and open an event handler.
- A URL carrying a dangerous scheme must be stripped rather than emitted.
What it means
The encoding MD-1 requires runs once, over the whole input, so nothing
downstream may run it again on a sequence the conversion itself already
wrote — a < in the source becomes < and stays <, never
&lt;.
The clause a careful reader still gets wrong is about quote characters, and it runs opposite to what "encode everything" suggests. A quote sitting in ordinary text is harmless and is left alone. The same character, once it lands inside a value placed between the double quotes of an attribute — a link target, an image source, an image's alternative text — has to be escaped there, because left alone it can end that attribute early and open a new one next to it.
Example
A quote inside ordinary text:
"He said \"hi\" and it's fine""<p>He said \"hi\" and it's fine</p>"The same character inside an image's alternative text:
"""<img src=\"a.png\" alt=\"x" onerror="alert(1)\">"