diff --git a/package-lock.json b/package-lock.json index d14500932..415fb3801 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4372,6 +4372,11 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz", "integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==" }, + "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 3597ed6a5..d2980e930 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "css-loader": "4.0.0", "cssnano-webpack-plugin": "1.0.3", "dropzone": "5.7.2", + "escape-goat": "3.0.0", "fast-glob": "3.2.4", "file-loader": "6.0.0", "fomantic-ui": "2.8.6", diff --git a/web_src/js/index.js b/web_src/js/index.js index 30a3d26ce..32fb340dc 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -4,6 +4,7 @@ import './publicpath.js'; import Vue from 'vue'; +import {htmlEscape} from 'escape-goat'; import 'jquery.are-you-sure'; import './vendor/semanticdropdown.js'; @@ -25,10 +26,6 @@ import {svg, svgs} from './svg.js'; const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; -function htmlEncode(text) { - return jQuery('
').text(text).html(); -} - let previewFileModes; const commentMDEditors = {}; @@ -528,12 +525,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')); @@ -1944,7 +1941,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, @@ -2220,7 +2217,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) - }
${htmlEncode(issue.repository.full_name)}
`, + name: `#${issue.number} ${htmlEscape(issue.title) + }
${htmlEscape(issue.repository.full_name)}
`, value: issue.id }); });