# HG changeset patch # User Mads Kiilerich # Date 2019-02-27 02:30:58 # Node ID 9376ca7157f37cecd7dc42eb56f906672fbc510d # Parent 04e44ea05c5fee8744879daf5b2c2e29051f8960 compare: correct display of special branch names in initial placeholder When a branch name contains special characters like '<' or '>', and a 'compare' operation is performed with such branch as one of the two compare sides, then the special branch name will be part of the URL, e.g. http://localhost:5000/myrepo/compare/branch@master...branch@%3Cscript%3Eblabla%3C/script%3E?other_repo=myrepo The encoded branch name is then used at page load as placeholders for the branch selection dropdowns. But, the special characters, were escaped too much, causing '<' to become < in the display of the dropdown. The placeholder was escaped via the default mako escape filter, before being passed to make_revision_dropdown, thus too early. We want the raw value. h.js() (copied from the default branch) gives us that, while still formatting and escaping the string so it is safe inside the script tag. diff --git a/kallithea/lib/helpers.py b/kallithea/lib/helpers.py --- a/kallithea/lib/helpers.py +++ b/kallithea/lib/helpers.py @@ -18,6 +18,7 @@ Consists of functions to typically be us available to Controllers. This module is available to both as 'h'. """ import hashlib +import json import StringIO import math import logging @@ -100,6 +101,36 @@ def html_escape(s): .replace("'", "'") ) +def js(value): + """Convert Python value to the corresponding JavaScript representation. + + This is necessary to safely insert arbitrary values into HTML " + is forbidden), the function ensures that the result never contains + '&', '<' and '>', thus making it safe in both those contexts (but + not in attributes). + """ + return literal( + ('(' + json.dumps(value) + ')') + # In JSON, the following can only appear in string literals. + .replace('&', r'\x26') + .replace('<', r'\x3c') + .replace('>', r'\x3e') + ) + def shorter(s, size=20): postfix = '...' if len(s) > size: diff --git a/kallithea/templates/compare/compare_diff.html b/kallithea/templates/compare/compare_diff.html --- a/kallithea/templates/compare/compare_diff.html +++ b/kallithea/templates/compare/compare_diff.html @@ -140,8 +140,8 @@ ${self.repo_context_bar('changelog')} }); } - make_revision_dropdown("#compare_org", "${'%s@%s' % (c.a_repo.repo_name, c.a_ref_name)}", "${c.a_repo.repo_name}", 'cache'); - make_revision_dropdown("#compare_other", "${'%s@%s' % (c.cs_repo.repo_name, c.cs_ref_name)}", "${c.cs_repo.repo_name}", 'cache2'); + make_revision_dropdown("#compare_org", ${h.js('%s@%s' % (c.a_repo.repo_name, c.a_ref_name))}, "${c.a_repo.repo_name}", 'cache'); + make_revision_dropdown("#compare_other", ${h.js('%s@%s' % (c.cs_repo.repo_name, c.cs_ref_name))}, "${c.cs_repo.repo_name}", 'cache2'); var values_changed = function() { var values = $('#compare_org').select2('data') && $('#compare_other').select2('data');