diff --git a/package-lock.json b/package-lock.json index 2f1c58073..87e6991dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4007,6 +4007,11 @@ "es6-symbol": "^3.1.1" } }, + "escape-goat": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", + "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==" + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", diff --git a/package.json b/package.json index ce14631d7..fe2c6193c 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "cssnano": "4.1.10", "domino": "2.1.5", "dropzone": "5.7.0", + "escape-goat": "3.0.0", "fast-glob": "3.2.2", "file-loader": "6.0.0", "fomantic-ui": "2.8.4", diff --git a/web_src/js/index.js b/web_src/js/index.js index 886520db6..6fe6d3777 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -6,6 +6,7 @@ import './publicpath.js'; import './polyfills.js'; import Vue from 'vue'; +import {htmlEscape} from 'escape-goat'; import 'jquery.are-you-sure'; import './vendor/semanticdropdown.js'; import {svg} from './utils.js'; @@ -25,10 +26,6 @@ import {createCodeEditor} from './features/codeeditor.js'; const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; -function htmlEncode(text) { - return jQuery('
').text(text).html(); -} - let previewFileModes; const commentMDEditors = {}; @@ -532,12 +529,12 @@ function initCommentForm() { switch (input_id) { case '#milestone_id': $list.find('.selected').html(`${ - htmlEncode($(this).text())}`); + htmlEscape($(this).text())}`); break; case '#assignee_id': $list.find('.selected').html(`` + `${ - htmlEncode($(this).text())}`); + htmlEscape($(this).text())}`); } $(`.ui${select_id}.list .no-select`).addClass('hide'); $(input_id).val($(this).data('id')); @@ -1942,7 +1939,7 @@ function searchUsers() { $.each(response.data, (_i, item) => { let title = item.login; if (item.full_name && item.full_name.length > 0) { - title += ` (${htmlEncode(item.full_name)})`; + title += ` (${htmlEscape(item.full_name)})`; } items.push({ title, @@ -2223,7 +2220,7 @@ function initTemplateSearch() { // Parse the response from the api to work with our dropdown $.each(response.data, (_r, repo) => { filteredResponse.results.push({ - name: htmlEncode(repo.full_name), + name: htmlEscape(repo.full_name), value: repo.id }); }); @@ -3500,8 +3497,8 @@ function initIssueList() { return; } filteredResponse.results.push({ - name: `#${issue.number} ${htmlEncode(issue.title) - }