the generic attribute writer used for these two spots does not escape what it
writes, so a value taken from the message ends the attribute and starts a new
one. both are inside a part that is compiled, which is where an injected
handler runs.
* the organizer link took inEvent.organizer.email verbatim. a value such as
mailto:x@y" onpointerover="... produced a live handler on the anchor, and an
entity encoded scheme such as javascript: reached the href, where the
browser decodes it. the href is now built as mailto: plus the parsed address
and escaped as an attribute value.
* the attachment name paragraph of the image and the link viewer took
filenameForDisplay verbatim. a quote inside an RFC 2231 encoded filename
ended the title attribute. the writer escapes & < > there but not the quote,
so the accessor drops the quote instead of escaping it, which keeps a plain
filename such as A&B.pdf unchanged in the tooltip.
the img title of the image viewer is left alone: attributes of that element are
escaped by the framework already.
the trailing while loop reuses the regex variable, which by then points at the
angular brace pattern whenever stripAngular is YES. that pattern has two
capture groups while the loop substitutes $1@im****$3, so NSRegularExpression
raises NSInvalidArgumentException and the NS_HANDLER swallows it.
give the @import pattern its own variable and use it in both the replacement
and the loop. the replacement also used the template of the block above, which
dropped the whole style element instead of masking the @import in place, so
test_stringWithoutHTMLInjection failed. it passes again, and a case with
stripAngular YES covers the loop.
the whole server built html of an iMIP card is rendered through sg-compile
(Message.service.js sets part.compile for UIxMailPartICalViewer), and the user
comment and the description are emitted with escapeHTML="NO". event data from
the invitation is therefore both an angular template and raw html.
47133fdf3 closed the description against interpolation with ng-non-bindable.
this closes both paths for every remaining field:
* ng-non-bindable on the user comment, the location, the organizer common name
and the raw body shown when the calendar cannot be parsed
* the user comment and the description are read through accessors that escape
them, so the url detection and insertBR produce the only markup left in the
output
the marker sits on the leaf containers, not on md-card-content, so the buttons,
the delegation autocomplete and the attendee chips keep being compiled. url
detection still turns a bare url in a comment or a description into a link.