summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/gfm_auto_complete.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/gfm_auto_complete.js')
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js23
1 files changed, 20 insertions, 3 deletions
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index 293cd2df16f..81da8409873 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -39,8 +39,18 @@ export const CONTACTS_REMOVE_COMMAND = '/remove_contacts';
* @param string user input
* @return {string} escaped user input
*/
-function escape(string) {
- return lodashEscape(string).replace(/\$/g, '$');
+export function escape(string) {
+ // To prevent double (or multiple) enconding attack
+ // Decode the user input repeatedly prior to escaping the final decoded string.
+ let encodedString = string;
+ let decodedString = decodeURIComponent(encodedString);
+
+ while (decodedString !== encodedString) {
+ encodedString = decodeURIComponent(decodedString);
+ decodedString = decodeURIComponent(encodedString);
+ }
+
+ return lodashEscape(decodedString.replace(/\$/g, '$'));
}
export function showAndHideHelper($input, alias = '') {
@@ -106,6 +116,7 @@ export const defaultAutocompleteConfig = {
issues: true,
mergeRequests: true,
epics: true,
+ iterations: true,
milestones: true,
labels: true,
snippets: true,
@@ -209,6 +220,10 @@ class GfmAutoComplete {
[[referencePrefix]] = value.params;
if (/^[@%~]/.test(referencePrefix)) {
tpl += '<%- referencePrefix %>';
+ } else if (/^[*]/.test(referencePrefix)) {
+ // EE-ONLY
+ referencePrefix = '*iteration:';
+ tpl += '<%- referencePrefix %>';
}
}
}
@@ -883,7 +898,8 @@ class GfmAutoComplete {
const atSymbolsWithBar = Object.keys(controllers)
.join('|')
.replace(/[$]/, '\\$&')
- .replace(/([[\]:])/g, '\\$1');
+ .replace(/([[\]:])/g, '\\$1')
+ .replace(/([*])/g, '\\$1');
const atSymbolsWithoutBar = Object.keys(controllers).join('');
const targetSubtext = subtext.split(GfmAutoComplete.regexSubtext).pop();
@@ -912,6 +928,7 @@ GfmAutoComplete.atTypeMap = {
'#': 'issues',
'!': 'mergeRequests',
'&': 'epics',
+ '*iteration:': 'iterations',
'~': 'labels',
'%': 'milestones',
'/': 'commands',