diff --git a/buildbot/status/web/base.py b/buildbot/status/web/base.py index 210e20c..64b0d5b 100644 --- a/buildbot/status/web/base.py +++ b/buildbot/status/web/base.py @@ -589,17 +589,37 @@ def changelinkfilter(changelink): def replace_from_tuple(t): search, url_replace = t[:2] if len(t) == 3: - title_replace = ' title="%s"' % t[2] + title_replace = t[2] else: title_replace = '' search_re = re.compile(search) - link_replace_re = jinja2.Markup(r'\g<0>' % (url_replace, title_replace)) + + def replacement_unmatched(text): + return jinja2.escape(text) + def replacement_matched(mo): + # expand things *after* application of the regular expressions + url = jinja2.escape(mo.expand(url_replace)) + title = jinja2.escape(mo.expand(title_replace)) + body = jinja2.escape(mo.group()) + if title: + return '%s' % (url, title, body) + else: + return '%s' % (url, body) def filter(text, project): - text = jinja2.escape(text) - html = search_re.sub(link_replace_re, text) - return html + # now, we need to split the string into matched and unmatched portions, + # quoting the unmatched portions directly and quoting the components of + # the 'a' element for the matched portions. We can't use re.split here, + # because the user-supplied patterns may have multiple groups. + html = [] + last_idx = 0 + for mo in search_re.finditer(text): + html.append(replacement_unmatched(text[last_idx:mo.start()])) + html.append(replacement_matched(mo)) + last_idx = mo.end() + html.append(replacement_unmatched(text[last_idx:])) + return jinja2.Markup(''.join(html)) return filter @@ -615,7 +635,7 @@ def changelinkfilter(changelink): if t: return replace_from_tuple(t)(text, project) else: - return jinja2.escape(text) + return cgi.escape(text) return dict_filter diff --git a/buildbot/status/web/templates/console.html b/buildbot/status/web/templates/console.html index 5568ca4..5743557 100644 --- a/buildbot/status/web/templates/console.html +++ b/buildbot/status/web/templates/console.html @@ -84,10 +84,10 @@ function checkMouseLeave(element, event) { {% if categories|length > 1 %} -
Categories: {% for c in categories %}{{ c.name }} {% endfor %} +
Categories: {% for c in categories %}{{ c.name|e }} {% endfor %} {% endif %} {% if branch != ANYBRANCH %} -
Branch: {{ branch }} +
Branch: {{ branch|e }} {% endif %} @@ -141,7 +141,7 @@ function checkMouseLeave(element, event) { {% for c in categories %} - {{ c.name }} + {{ c.name|e }} {% endfor %} @@ -191,7 +191,7 @@ function checkMouseLeave(element, event) { {% for b in r.builds[c.name] %} {% endfor %}