diff --git a/kallithea/controllers/admin/my_account.py b/kallithea/controllers/admin/my_account.py --- a/kallithea/controllers/admin/my_account.py +++ b/kallithea/controllers/admin/my_account.py @@ -41,7 +41,6 @@ from kallithea.lib import auth_modules from kallithea.lib.auth import LoginRequired, NotAnonymous, AuthUser from kallithea.lib.base import BaseController, render from kallithea.lib.utils2 import generate_api_key, safe_int -from kallithea.lib.compat import json from kallithea.model.db import Repository, UserEmailMap, User, UserFollowing from kallithea.model.forms import UserForm, PasswordChangeForm from kallithea.model.user import UserModel @@ -84,10 +83,8 @@ class MyAccountController(BaseController .filter(Repository.owner_id == request.authuser.user_id).all() - repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list, + return RepoModel().get_repos_as_dict(repos_list=repos_list, admin=admin) - #json used to render the grid - return json.dumps(repos_data) def my_account(self): c.active = 'profile' @@ -176,7 +173,7 @@ class MyAccountController(BaseController c.active = 'repos' self.__load_data() - #json used to render the grid + #data used to render the grid c.data = self._load_my_repos_data() return render('admin/my_account/my_account.html') @@ -184,7 +181,7 @@ class MyAccountController(BaseController c.active = 'watched' self.__load_data() - #json used to render the grid + #data used to render the grid c.data = self._load_my_repos_data(watched=True) return render('admin/my_account/my_account.html') diff --git a/kallithea/controllers/admin/repo_groups.py b/kallithea/controllers/admin/repo_groups.py --- a/kallithea/controllers/admin/repo_groups.py +++ b/kallithea/controllers/admin/repo_groups.py @@ -39,7 +39,6 @@ from webob.exc import HTTPFound, HTTPFor import kallithea from kallithea.config.routing import url from kallithea.lib import helpers as h -from kallithea.lib.compat import json from kallithea.lib.auth import LoginRequired, \ HasRepoGroupPermissionLevelDecorator, HasRepoGroupPermissionLevel, \ HasPermissionAny @@ -141,13 +140,13 @@ class RepoGroupsController(BaseControlle repo_count) }) - c.data = json.dumps({ + c.data = { "totalRecords": total_records, "startIndex": 0, "sort": None, "dir": "asc", "records": repo_groups_data - }) + } return render('admin/repo_groups/repo_groups.html') @@ -304,8 +303,8 @@ class RepoGroupsController(BaseControlle repos_list = Repository.query(sorted=True).filter_by(group=c.group).all() repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list, admin=False, short_name=True) - #json used to render the grid - c.data = json.dumps(repos_data) + # data used to render the grid + c.data = repos_data return render('admin/repo_groups/repo_group_show.html') diff --git a/kallithea/controllers/admin/repos.py b/kallithea/controllers/admin/repos.py --- a/kallithea/controllers/admin/repos.py +++ b/kallithea/controllers/admin/repos.py @@ -47,7 +47,6 @@ from kallithea.model.db import User, Rep from kallithea.model.forms import RepoForm, RepoFieldForm, RepoPermsForm from kallithea.model.scm import ScmModel, AvailableRepoGroupChoices, RepoList from kallithea.model.repo import RepoModel -from kallithea.lib.compat import json from kallithea.lib.exceptions import AttachedForksError from kallithea.lib.utils2 import safe_int @@ -105,8 +104,8 @@ class ReposController(BaseRepoController repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list, admin=True, super_user_actions=True) - #json used to render the grid - c.data = json.dumps(repos_data) + #data used to render the grid + c.data = repos_data return render('admin/repos/repos.html') diff --git a/kallithea/controllers/admin/user_groups.py b/kallithea/controllers/admin/user_groups.py --- a/kallithea/controllers/admin/user_groups.py +++ b/kallithea/controllers/admin/user_groups.py @@ -56,7 +56,6 @@ from kallithea.model.forms import UserGr CustomDefaultPermissionsForm from kallithea.model.meta import Session from kallithea.lib.utils import action_logger -from kallithea.lib.compat import json log = logging.getLogger(__name__) @@ -119,13 +118,13 @@ class UserGroupsController(BaseControlle "action": user_group_actions(user_gr.users_group_id, user_gr.users_group_name) }) - c.data = json.dumps({ + c.data = { "totalRecords": total_records, "startIndex": 0, "sort": None, "dir": "asc", "records": user_groups_data - }) + } return render('admin/user_groups/user_groups.html') diff --git a/kallithea/controllers/admin/users.py b/kallithea/controllers/admin/users.py --- a/kallithea/controllers/admin/users.py +++ b/kallithea/controllers/admin/users.py @@ -51,7 +51,6 @@ from kallithea.model.forms import UserFo from kallithea.model.user import UserModel from kallithea.model.meta import Session from kallithea.lib.utils import action_logger -from kallithea.lib.compat import json from kallithea.lib.utils2 import datetime_to_time, safe_int, generate_api_key log = logging.getLogger(__name__) @@ -103,13 +102,13 @@ class UsersController(BaseController): "action": user_actions(user.user_id, user.username), }) - c.data = json.dumps({ + c.data = { "totalRecords": total_records, "startIndex": 0, "sort": None, "dir": "asc", "records": users_data - }) + } return render('admin/users/users.html') diff --git a/kallithea/controllers/changelog.py b/kallithea/controllers/changelog.py --- a/kallithea/controllers/changelog.py +++ b/kallithea/controllers/changelog.py @@ -36,7 +36,6 @@ import kallithea.lib.helpers as h from kallithea.config.routing import url from kallithea.lib.auth import LoginRequired, HasRepoPermissionLevelDecorator from kallithea.lib.base import BaseRepoController, render -from kallithea.lib.compat import json from kallithea.lib.graphmod import graph_data from kallithea.lib.page import RepoPage from kallithea.lib.vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \ @@ -171,7 +170,7 @@ class ChangelogController(BaseRepoContro revs = [] if not f_path: revs = [x.revision for x in c.pagination] - c.jsdata = json.dumps(graph_data(c.db_repo_scm_instance, revs)) + c.jsdata = graph_data(c.db_repo_scm_instance, revs) c.revision = revision # requested revision ref c.first_revision = c.pagination[0] # pagination is never empty here! diff --git a/kallithea/controllers/changeset.py b/kallithea/controllers/changeset.py --- a/kallithea/controllers/changeset.py +++ b/kallithea/controllers/changeset.py @@ -36,7 +36,6 @@ from webob.exc import HTTPFound, HTTPFor from kallithea.lib.vcs.exceptions import RepositoryError, \ ChangesetDoesNotExistError, EmptyRepositoryError -from kallithea.lib.compat import json import kallithea.lib.helpers as h from kallithea.lib.auth import LoginRequired, HasRepoPermissionLevelDecorator, \ NotAnonymous @@ -333,7 +332,7 @@ class ChangesetController(BaseRepoContro c.cs_ranges_org = None c.cs_comments = {} revs = [ctx.revision for ctx in reversed(c.cs_ranges)] - c.jsdata = json.dumps(graph_data(c.db_repo_scm_instance, revs)) + c.jsdata = graph_data(c.db_repo_scm_instance, revs) return render('changeset/changeset_range.html') @LoginRequired() diff --git a/kallithea/controllers/compare.py b/kallithea/controllers/compare.py --- a/kallithea/controllers/compare.py +++ b/kallithea/controllers/compare.py @@ -45,7 +45,6 @@ from kallithea.model.db import Repositor from kallithea.lib.diffs import LimitedDiffContainer from kallithea.controllers.changeset import _ignorews_url, _context_url from kallithea.lib.graphmod import graph_data -from kallithea.lib.compat import json, OrderedDict log = logging.getLogger(__name__) @@ -227,7 +226,7 @@ class CompareController(BaseRepoControll c.statuses = c.cs_repo.statuses(raw_ids) revs = [ctx.revision for ctx in reversed(c.cs_ranges)] - c.jsdata = json.dumps(graph_data(c.cs_repo.scm_instance, revs)) + c.jsdata = graph_data(c.cs_repo.scm_instance, revs) if partial: return render('compare/compare_cs.html') diff --git a/kallithea/controllers/home.py b/kallithea/controllers/home.py --- a/kallithea/controllers/home.py +++ b/kallithea/controllers/home.py @@ -34,7 +34,6 @@ from webob.exc import HTTPBadRequest from sqlalchemy.sql.expression import func from kallithea.lib.utils import conditional_cache -from kallithea.lib.compat import json from kallithea.lib.auth import LoginRequired, HasRepoPermissionLevelDecorator from kallithea.lib.base import BaseController, render, jsonify from kallithea.model.db import Repository, RepoGroup @@ -61,8 +60,8 @@ class HomeController(BaseController): repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list, admin=False, short_name=True) - #json used to render the grid - c.data = json.dumps(repos_data) + #data used to render the grid + c.data = repos_data return render('/index.html') diff --git a/kallithea/controllers/journal.py b/kallithea/controllers/journal.py --- a/kallithea/controllers/journal.py +++ b/kallithea/controllers/journal.py @@ -48,7 +48,6 @@ from kallithea.model.repo import RepoMod import kallithea.lib.helpers as h from kallithea.lib.auth import LoginRequired, NotAnonymous from kallithea.lib.base import BaseController, render -from kallithea.lib.compat import json from kallithea.lib.page import Page from kallithea.lib.utils2 import safe_int, AttributeDict @@ -218,8 +217,8 @@ class JournalController(BaseController): repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list, admin=True) - #json used to render the grid - c.data = json.dumps(repos_data) + #data used to render the grid + c.data = repos_data return render('journal/journal.html') diff --git a/kallithea/controllers/pullrequests.py b/kallithea/controllers/pullrequests.py --- a/kallithea/controllers/pullrequests.py +++ b/kallithea/controllers/pullrequests.py @@ -40,7 +40,6 @@ from kallithea.lib import diffs from kallithea.lib.auth import LoginRequired, HasRepoPermissionLevelDecorator, \ NotAnonymous from kallithea.lib.base import BaseRepoController, render, jsonify -from kallithea.lib.compat import json, OrderedDict from kallithea.lib.diffs import LimitedDiffContainer from kallithea.lib.page import Page from kallithea.lib.utils import action_logger @@ -619,7 +618,7 @@ class PullrequestsController(BaseRepoCon 'error') c.cs_ranges_org = None # not stored and not important and moving target - could be calculated ... revs = [ctx.revision for ctx in reversed(c.cs_ranges)] - c.jsdata = json.dumps(graph_data(org_scm_instance, revs)) + c.jsdata = graph_data(org_scm_instance, revs) c.is_range = False try: @@ -701,7 +700,7 @@ class PullrequestsController(BaseRepoCon c.avail_revs = avail_revs c.avail_cs = [org_scm_instance.get_changeset(r) for r in avail_show] - c.avail_jsdata = json.dumps(graph_data(org_scm_instance, avail_show)) + c.avail_jsdata = graph_data(org_scm_instance, avail_show) raw_ids = [x.raw_id for x in c.cs_ranges] c.cs_comments = c.cs_repo.get_comments(raw_ids) diff --git a/kallithea/controllers/summary.py b/kallithea/controllers/summary.py --- a/kallithea/controllers/summary.py +++ b/kallithea/controllers/summary.py @@ -146,12 +146,12 @@ class SummaryController(BaseRepoControll "desc": LANGUAGES_EXTENSIONS_MAP.get(x)}) for x, y in lang_stats_d.items()) - c.trending_languages = json.dumps( + c.trending_languages = ( sorted(lang_stats, reverse=True, key=lambda k: k[1])[:10] ) else: c.no_data = True - c.trending_languages = json.dumps([]) + c.trending_languages = [] c.enable_downloads = c.db_repo.enable_downloads c.readme_data, c.readme_file = \ @@ -202,7 +202,7 @@ class SummaryController(BaseRepoControll "desc": LANGUAGES_EXTENSIONS_MAP.get(x)}) for x, y in lang_stats_d.items()) - c.trending_languages = json.dumps( + c.trending_languages = ( sorted(lang_stats, reverse=True, key=lambda k: k[1])[:10] ) last_rev = stats.stat_on_revision + 1 @@ -214,9 +214,9 @@ class SummaryController(BaseRepoControll c.stats_percentage = '%.2f' % ((float((last_rev)) / c.repo_last_rev) * 100) else: - c.commit_data = json.dumps({}) - c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10]]) - c.trending_languages = json.dumps({}) + c.commit_data = {} + c.overview_data = ([[ts_min_y, 0], [ts_max_y, 10]]) + c.trending_languages = {} c.no_data = True recurse_limit = 500 # don't recurse more than 500 times when parsing 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 logging import re @@ -85,6 +86,50 @@ 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 jshtml(val): + """HTML escapes a string value, then converts the resulting string + to its corresponding JavaScript representation (see `js`). + + This is used when a plain-text string (possibly containing special + HTML characters) will be used by a script in an HTML context (e.g. + element.innerHTML or jQuery's 'html' method). + + If in doubt, err on the side of using `jshtml` over `js`, since it's + better to escape too much than too little. + """ + return js(escape(val)) + + def shorter(s, size=20, firstline=False, postfix='...'): """Truncate s to size, including the postfix string if truncating. If firstline, truncate at newline. diff --git a/kallithea/model/repo.py b/kallithea/model/repo.py --- a/kallithea/model/repo.py +++ b/kallithea/model/repo.py @@ -35,7 +35,6 @@ from sqlalchemy.orm import subqueryload from kallithea.lib.utils import make_ui from kallithea.lib.vcs.backends import get_backend -from kallithea.lib.compat import json from kallithea.lib.utils2 import LazyProperty, safe_str, safe_unicode, \ remove_prefix, obfuscate_url_pw, get_current_authuser from kallithea.lib.caching_query import FromCache @@ -127,7 +126,7 @@ class RepoModel(object): .filter(User.active == True) \ .order_by(User.name, User.lastname) \ .all() - return json.dumps([ + return [ { 'id': u.user_id, 'fname': h.escape(u.name), @@ -136,7 +135,6 @@ class RepoModel(object): 'gravatar_lnk': h.gravatar_url(u.email, size=28, default='default'), 'gravatar_size': 14, } for u in users] - ) def get_user_groups_js(self): user_groups = UserGroup.query() \ @@ -145,13 +143,12 @@ class RepoModel(object): .options(subqueryload(UserGroup.members)) \ .all() user_groups = UserGroupList(user_groups, perm_level='read') - return json.dumps([ + return [ { 'id': gr.users_group_id, 'grname': gr.users_group_name, 'grmembers': len(gr.members), } for gr in user_groups] - ) @classmethod def _render_datatable(cls, tmpl, *args, **kwargs): diff --git a/kallithea/templates/admin/admin.html b/kallithea/templates/admin/admin.html --- a/kallithea/templates/admin/admin.html +++ b/kallithea/templates/admin/admin.html @@ -46,7 +46,7 @@ $(document).ready(function() { $('#filter_form').submit(function (e) { e.preventDefault(); var val = $('#j_filter').val(); - window.location = "${url.current(filter='__FILTER__')}".replace('__FILTER__',val); + window.location = ${h.js(url.current(filter='__FILTER__'))}.replace('__FILTER__',val); }); fix_j_filter_width($('#j_filter').val().length); }); diff --git a/kallithea/templates/admin/gists/edit.html b/kallithea/templates/admin/gists/edit.html --- a/kallithea/templates/admin/gists/edit.html +++ b/kallithea/templates/admin/gists/edit.html @@ -81,10 +81,10 @@ ## dynamic edit box. diff --git a/kallithea/templates/admin/notifications/show_notification.html b/kallithea/templates/admin/notifications/show_notification.html --- a/kallithea/templates/admin/notifications/show_notification.html +++ b/kallithea/templates/admin/notifications/show_notification.html @@ -43,8 +43,8 @@ diff --git a/kallithea/templates/admin/repo_groups/repo_groups.html b/kallithea/templates/admin/repo_groups/repo_groups.html --- a/kallithea/templates/admin/repo_groups/repo_groups.html +++ b/kallithea/templates/admin/repo_groups/repo_groups.html @@ -31,16 +31,16 @@ diff --git a/kallithea/templates/admin/repos/repo_edit_settings.html b/kallithea/templates/admin/repos/repo_edit_settings.html --- a/kallithea/templates/admin/repos/repo_edit_settings.html +++ b/kallithea/templates/admin/repos/repo_edit_settings.html @@ -125,7 +125,7 @@ ${h.form(url('update_repo', repo_name=c. }); // autocomplete - var _USERS_AC_DATA = ${c.users_array|n}; + var _USERS_AC_DATA = ${h.js(c.users_array)}; SimpleUserAutoComplete($('#owner'), $('#owner_container'), _USERS_AC_DATA); }); diff --git a/kallithea/templates/admin/repos/repos.html b/kallithea/templates/admin/repos/repos.html --- a/kallithea/templates/admin/repos/repos.html +++ b/kallithea/templates/admin/repos/repos.html @@ -30,18 +30,18 @@ diff --git a/kallithea/templates/admin/user_groups/user_group_edit_perms.html b/kallithea/templates/admin/user_groups/user_group_edit_perms.html --- a/kallithea/templates/admin/user_groups/user_group_edit_perms.html +++ b/kallithea/templates/admin/user_groups/user_group_edit_perms.html @@ -75,7 +75,7 @@ ${h.form(url('edit_user_group_perms_upda %endfor <% - _tmpl = h.literal("""'\ + _tmpl = """\ \ \ \ @@ -87,7 +87,7 @@ ${h.form(url('edit_user_group_perms_upda
\ \ \ - '""") + """ %> ## ADD HERE DYNAMICALLY NEW INPUTS FROM THE '_tmpl' @@ -110,7 +110,7 @@ ${h.end_form()} diff --git a/kallithea/templates/admin/user_groups/user_groups.html b/kallithea/templates/admin/user_groups/user_groups.html --- a/kallithea/templates/admin/user_groups/user_groups.html +++ b/kallithea/templates/admin/user_groups/user_groups.html @@ -30,17 +30,17 @@ @@ -82,22 +82,22 @@ tooltip_activate(); show_more_event(); // routes registration - pyroutes.register('home', "${h.url('home')}", []); - pyroutes.register('new_gist', "${h.url('new_gist')}", []); - pyroutes.register('gists', "${h.url('gists')}", []); - pyroutes.register('new_repo', "${h.url('new_repo')}", []); + pyroutes.register('home', ${h.js(h.url('home'))}, []); + pyroutes.register('new_gist', ${h.js(h.url('new_gist'))}, []); + pyroutes.register('gists', ${h.js(h.url('gists'))}, []); + pyroutes.register('new_repo', ${h.js(h.url('new_repo'))}, []); - pyroutes.register('summary_home', "${h.url('summary_home', repo_name='%(repo_name)s')}", ['repo_name']); - pyroutes.register('changelog_home', "${h.url('changelog_home', repo_name='%(repo_name)s')}", ['repo_name']); - pyroutes.register('files_home', "${h.url('files_home', repo_name='%(repo_name)s',revision='%(revision)s',f_path='%(f_path)s')}", ['repo_name', 'revision', 'f_path']); - pyroutes.register('edit_repo', "${h.url('edit_repo', repo_name='%(repo_name)s')}", ['repo_name']); - pyroutes.register('edit_repo_perms', "${h.url('edit_repo_perms', repo_name='%(repo_name)s')}", ['repo_name']); - pyroutes.register('pullrequest_home', "${h.url('pullrequest_home', repo_name='%(repo_name)s')}", ['repo_name']); + pyroutes.register('summary_home', ${h.js(h.url('summary_home', repo_name='%(repo_name)s'))}, ['repo_name']); + pyroutes.register('changelog_home', ${h.js(h.url('changelog_home', repo_name='%(repo_name)s'))}, ['repo_name']); + pyroutes.register('files_home', ${h.js(h.url('files_home', repo_name='%(repo_name)s',revision='%(revision)s',f_path='%(f_path)s'))}, ['repo_name', 'revision', 'f_path']); + pyroutes.register('edit_repo', ${h.js(h.url('edit_repo', repo_name='%(repo_name)s'))}, ['repo_name']); + pyroutes.register('edit_repo_perms', ${h.js(h.url('edit_repo_perms', repo_name='%(repo_name)s'))}, ['repo_name']); + pyroutes.register('pullrequest_home', ${h.js(h.url('pullrequest_home', repo_name='%(repo_name)s'))}, ['repo_name']); - pyroutes.register('toggle_following', "${h.url('toggle_following')}"); - pyroutes.register('changeset_info', "${h.url('changeset_info', repo_name='%(repo_name)s', revision='%(revision)s')}", ['repo_name', 'revision']); - pyroutes.register('repo_size', "${h.url('repo_size', repo_name='%(repo_name)s')}", ['repo_name']); - pyroutes.register('repo_refs_data', "${h.url('repo_refs_data', repo_name='%(repo_name)s')}", ['repo_name']); + pyroutes.register('toggle_following', ${h.js(h.url('toggle_following'))}); + pyroutes.register('changeset_info', ${h.js(h.url('changeset_info', repo_name='%(repo_name)s', revision='%(revision)s'))}, ['repo_name', 'revision']); + pyroutes.register('repo_size', ${h.js(h.url('repo_size', repo_name='%(repo_name)s'))}, ['repo_name']); + pyroutes.register('repo_refs_data', ${h.js(h.url('repo_refs_data', repo_name='%(repo_name)s'))}, ['repo_name']); }); diff --git a/kallithea/templates/changelog/changelog.html b/kallithea/templates/changelog/changelog.html --- a/kallithea/templates/changelog/changelog.html +++ b/kallithea/templates/changelog/changelog.html @@ -189,7 +189,7 @@ ${self.repo_context_bar('changelog', c.f $(document).ready(function(){ var $checkboxes = $('.changeset_range'); - pyroutes.register('changeset_home', "${h.url('changeset_home', repo_name='%(repo_name)s', revision='%(revision)s')}", ['repo_name', 'revision']); + pyroutes.register('changeset_home', ${h.js(h.url('changeset_home', repo_name='%(repo_name)s', revision='%(revision)s'))}, ['repo_name', 'revision']); var checkbox_checker = function(e) { var $checked_checkboxes = $checkboxes.filter(':checked'); @@ -206,19 +206,19 @@ ${self.repo_context_bar('changelog', c.f if ($checked_checkboxes.length > 1 || singlerange) { var rev_start = $checked_checkboxes.last().prop('name'); $('#rev_range_container').prop('href', - pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}', + pyroutes.url('changeset_home', {'repo_name': ${h.js(c.repo_name)}, 'revision': rev_start + '...' + rev_end})); $('#rev_range_container').html( _TM['Show Selected Changesets {0} → {1}'].format(rev_start.substr(0, 12), rev_end.substr(0, 12))); $('#rev_range_container').show(); $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home', - {'repo_name': '${c.repo_name}', + {'repo_name': ${h.js(c.repo_name)}, 'rev_start': rev_start, 'rev_end': rev_end})); $('#open_new_pr').html(_TM['Open New Pull Request for {0} → {1}'].format(rev_start.substr(0, 12), rev_end.substr(0, 12))); } else { $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home', - {'repo_name': '${c.repo_name}', + {'repo_name': ${h.js(c.repo_name)}, 'rev_end': rev_end})); $('#open_new_pr').html(_TM['Open New Pull Request from {0}'].format(rev_end.substr(0, 12))); } @@ -252,14 +252,14 @@ ${self.repo_context_bar('changelog', c.f $('#rev_range_clear').hide(); %if c.revision: $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home', - {'repo_name': '${c.repo_name}', - 'rev_end':'${c.first_revision.raw_id}'})); - $('#open_new_pr').html(_TM['Open New Pull Request from {0}'].format('${c.revision}')); + {'repo_name': ${h.js(c.repo_name)}, + 'rev_end':${h.js(c.first_revision.raw_id)}})); + $('#open_new_pr').html(_TM['Open New Pull Request from {0}'].format(${h.jshtml(c.revision)})); %else: $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home', - {'repo_name': '${c.repo_name}', - 'branch':'${c.first_revision.branch}'})); - $('#open_new_pr').html(_TM['Open New Pull Request from {0}'].format('${c.first_revision.branch}')); + {'repo_name': ${h.js(c.repo_name)}, + 'branch':${h.js(c.first_revision.branch)}})); + $('#open_new_pr').html(_TM['Open New Pull Request from {0}'].format(${h.jshtml(c.first_revision.branch)})); %endif $('#compare_fork').show(); $checkboxes.closest('tr').removeClass('out-of-range'); @@ -311,15 +311,15 @@ ${self.repo_context_bar('changelog', c.f $("#branch_filter").change(function(e){ var selected_branch = e.currentTarget.options[e.currentTarget.selectedIndex].value; if(selected_branch != ''){ - window.location = pyroutes.url('changelog_home', {'repo_name': '${c.repo_name}', + window.location = pyroutes.url('changelog_home', {'repo_name': ${h.js(c.repo_name)}, 'branch': selected_branch}); }else{ - window.location = pyroutes.url('changelog_home', {'repo_name': '${c.repo_name}'}); + window.location = pyroutes.url('changelog_home', {'repo_name': ${h.js(c.repo_name)}}); } $("#changelog").hide(); }); - var jsdata = ${c.jsdata|n}; + var jsdata = ${h.js(c.jsdata)}; var r = new BranchRenderer('graph_canvas', 'graph_content', 'chg_'); r.render(jsdata); }); diff --git a/kallithea/templates/changeset/changeset.html b/kallithea/templates/changeset/changeset.html --- a/kallithea/templates/changeset/changeset.html +++ b/kallithea/templates/changeset/changeset.html @@ -23,10 +23,10 @@ ${self.repo_context_bar('changelog', c.c ${self.breadcrumbs()}
@@ -217,7 +217,7 @@ ${self.repo_context_bar('changelog', c.c move_comments($(".comments .comments-list-chunk")); pyroutes.register('changeset_home', - "${h.url('changeset_home', repo_name='%(repo_name)s', revision='%(revision)s')}", + ${h.js(h.url('changeset_home', repo_name='%(repo_name)s', revision='%(revision)s'))}, ['repo_name', 'revision']); //next links @@ -226,15 +226,15 @@ ${self.repo_context_bar('changelog', c.c //>1 links show them to user to choose if(!$('#child_link').hasClass('disabled')){ $.ajax({ - url: '${h.url('changeset_children',repo_name=c.repo_name, revision=c.changeset.raw_id)}', + url: ${h.js(h.url('changeset_children',repo_name=c.repo_name, revision=c.changeset.raw_id))}, success: function(data) { if(data.results.length === 0){ $('#child_link').addClass('disabled'); - $('#child_link').html('${_('No revisions')}'); + $('#child_link').html(${h.jshtml(_('No revisions'))}); } if(data.results.length === 1){ var commit = data.results[0]; - window.location = pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': commit.raw_id}); + window.location = pyroutes.url('changeset_home', {'repo_name': ${h.js(c.repo_name)},'revision': commit.raw_id}); } else if(data.results.length === 2){ $('#child_link').addClass('disabled'); @@ -243,12 +243,12 @@ ${self.repo_context_bar('changelog', c.c _html +='__rev__ ' .replace('__rev__','r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0,6))) .replace('__title__', data.results[0].message) - .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[0].raw_id})); + .replace('__url__', pyroutes.url('changeset_home', {'repo_name': ${h.js(c.repo_name)},'revision': data.results[0].raw_id})); _html +='
' _html +='__rev__ ' .replace('__rev__','r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0,6))) .replace('__title__', data.results[1].message) - .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[1].raw_id})); + .replace('__url__', pyroutes.url('changeset_home', {'repo_name': ${h.js(c.repo_name)},'revision': data.results[1].raw_id})); $('#child_link').html(_html); } } @@ -263,15 +263,15 @@ ${self.repo_context_bar('changelog', c.c //>1 links show them to user to choose if(!$('#parent_link').hasClass('disabled')){ $.ajax({ - url: '${h.url('changeset_parents',repo_name=c.repo_name, revision=c.changeset.raw_id)}', + url: ${h.js(h.url('changeset_parents',repo_name=c.repo_name, revision=c.changeset.raw_id))}, success: function(data) { if(data.results.length === 0){ $('#parent_link').addClass('disabled'); - $('#parent_link').html('${_('No revisions')}'); + $('#parent_link').html(${h.jshtml(_('No revisions'))}); } if(data.results.length === 1){ var commit = data.results[0]; - window.location = pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': commit.raw_id}); + window.location = pyroutes.url('changeset_home', {'repo_name': ${h.js(c.repo_name)},'revision': commit.raw_id}); } else if(data.results.length === 2){ $('#parent_link').addClass('disabled'); @@ -280,12 +280,12 @@ ${self.repo_context_bar('changelog', c.c _html +=' __rev__' .replace('__rev__','r{0}:{1}'.format(data.results[0].revision, data.results[0].raw_id.substr(0,6))) .replace('__title__', data.results[0].message) - .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[0].raw_id})); + .replace('__url__', pyroutes.url('changeset_home', {'repo_name': ${h.js(c.repo_name)},'revision': data.results[0].raw_id})); _html +='
' _html +=' __rev__' .replace('__rev__','r{0}:{1}'.format(data.results[1].revision, data.results[1].raw_id.substr(0,6))) .replace('__title__', data.results[1].message) - .replace('__url__', pyroutes.url('changeset_home', {'repo_name': '${c.repo_name}','revision': data.results[1].raw_id})); + .replace('__url__', pyroutes.url('changeset_home', {'repo_name': ${h.js(c.repo_name)},'revision': data.results[1].raw_id})); $('#parent_link').html(_html); } } diff --git a/kallithea/templates/compare/compare_cs.html b/kallithea/templates/compare/compare_cs.html --- a/kallithea/templates/compare/compare_cs.html +++ b/kallithea/templates/compare/compare_cs.html @@ -121,7 +121,7 @@
%if c.as_form: - + %else: %endif @@ -130,7 +130,7 @@ $(document).ready(function(){ %if not c.as_form: - var jsdata = ${c.jsdata|n}; + var jsdata = ${h.js(c.jsdata)}; var r = new BranchRenderer('graph_canvas', 'graph_content_pr', 'chg_'); r.render(jsdata); %endif 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 @@ -149,8 +149,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.jshtml('%s@%s' % (c.a_repo.repo_name, c.a_ref_name))}, ${h.jshtml(c.a_repo.repo_name)}, 'cache'); + make_revision_dropdown("#compare_other", ${h.jshtml('%s@%s' % (c.cs_repo.repo_name, c.cs_ref_name))}, ${h.jshtml(c.cs_repo.repo_name)}, 'cache2'); var values_changed = function() { var values = $('#compare_org').select2('data') && $('#compare_other').select2('data'); @@ -172,7 +172,7 @@ ${self.repo_context_bar('changelog')} return; } - var compare_url = "${h.url('compare_url',repo_name=c.repo_name,org_ref_type='__other_ref_type__',org_ref_name='__org__',other_ref_type='__org_ref_type__',other_ref_name='__other__', other_repo=c.cs_repo.repo_name)}"; + var compare_url = ${h.js(h.url('compare_url',repo_name=c.repo_name,org_ref_type='__other_ref_type__',org_ref_name='__org__',other_ref_type='__org_ref_type__',other_ref_name='__other__', other_repo=c.cs_repo.repo_name))}; var u = compare_url.replace('__other_ref_type__',org.type) .replace('__org__',org.text) .replace('__org_ref_type__',other.type) diff --git a/kallithea/templates/files/diff_2way.html b/kallithea/templates/files/diff_2way.html --- a/kallithea/templates/files/diff_2way.html +++ b/kallithea/templates/files/diff_2way.html @@ -61,8 +61,8 @@ ${self.repo_context_bar('changelog')}
@@ -372,7 +372,7 @@ ${self.repo_context_bar('showpullrequest show_comment_form($(this)); }); - var avail_jsdata = ${c.avail_jsdata|n}; + var avail_jsdata = ${h.js(c.avail_jsdata)}; var avail_r = new BranchRenderer('avail_graph_canvas', 'updaterevs-table', 'chg_available_'); avail_r.render(avail_jsdata); diff --git a/kallithea/templates/register.html b/kallithea/templates/register.html --- a/kallithea/templates/register.html +++ b/kallithea/templates/register.html @@ -92,7 +92,7 @@ $('#username').focus(); %if c.captcha_active: - Recaptcha.create("${c.captcha_public_key}", "recaptcha", + Recaptcha.create(${h.js(c.captcha_public_key)}, "recaptcha", { theme: "white" } diff --git a/kallithea/templates/summary/statistics.html b/kallithea/templates/summary/statistics.html --- a/kallithea/templates/summary/statistics.html +++ b/kallithea/templates/summary/statistics.html @@ -53,7 +53,7 @@ ${self.repo_context_bar('summary')} diff --git a/kallithea/templates/summary/summary.html b/kallithea/templates/summary/summary.html --- a/kallithea/templates/summary/summary.html +++ b/kallithea/templates/summary/summary.html @@ -43,7 +43,7 @@ redirect_hash_branch = function(){ var branch = window.location.hash.replace(/^#(.*)/, '$1'); if (branch){ - window.location = "${h.url('changelog_home',repo_name=c.repo_name,branch='__BRANCH__')}" + window.location = ${h.js(h.url('changelog_home',repo_name=c.repo_name,branch='__BRANCH__'))} .replace('__BRANCH__',branch); } } @@ -252,7 +252,7 @@ $(document).ready(function(){ query.callback(data); }else{ $.ajax({ - url: pyroutes.url('repo_refs_data', {'repo_name': '${c.repo_name}'}), + url: pyroutes.url('repo_refs_data', {'repo_name': ${h.js(c.repo_name)}}), data: {}, dataType: 'json', type: 'GET', @@ -271,7 +271,7 @@ $(document).ready(function(){ for(k in tmpl_links){ var s = $('#'+k+'_link'); if(s){ - var title_tmpl = "${_('Download %s as %s') % ('__CS_NAME__','__CS_EXT__')}"; + var title_tmpl = ${h.jshtml(_('Download %s as %s') % ('__CS_NAME__','__CS_EXT__'))}; title_tmpl= title_tmpl.replace('__CS_NAME__',new_cs.text); title_tmpl = title_tmpl.replace('__CS_EXT__',k); title_tmpl = ' '+ title_tmpl; @@ -287,7 +287,7 @@ $(document).ready(function(){ var tmpl_links = {}; %for cnt,archive in enumerate(c.db_repo_scm_instance._get_archives()): - tmpl_links["${archive['type']}"] = '${h.link_to('__NAME__', h.url('files_archive_home',repo_name=c.db_repo.repo_name, fname='__CS__'+archive['extension'],subrepos='__SUB__'),class_='btn btn-default btn-sm')}'; + tmpl_links[${h.jshtml(archive['type'])}] = ${h.js(h.link_to('__NAME__', h.url('files_archive_home',repo_name=c.db_repo.repo_name, fname='__CS__'+archive['extension'],subrepos='__SUB__'),class_='btn btn-default btn-sm'))}; %endfor }); @@ -295,7 +295,7 @@ $(document).ready(function(){ %if c.show_stats: