Commit 25ec18e3 authored by Phil Hughes's avatar Phil Hughes

Correctly escape regex in GFM autocomplete

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/343358
parent 8e1fbdf4
import $ from 'jquery'; import $ from 'jquery';
import '~/lib/utils/jquery_at_who'; import '~/lib/utils/jquery_at_who';
import { escape as lodashEscape, sortBy, template } from 'lodash'; import { escape as lodashEscape, sortBy, template, escapeRegExp } from 'lodash';
import * as Emoji from '~/emoji'; import * as Emoji from '~/emoji';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { s__, __, sprintf } from '~/locale'; import { s__, __, sprintf } from '~/locale';
...@@ -65,6 +65,17 @@ export function membersBeforeSave(members) { ...@@ -65,6 +65,17 @@ export function membersBeforeSave(members) {
}); });
} }
export const highlighter = (li, query) => {
// override default behaviour to escape dot character
// see https://github.com/ichord/At.js/pull/576
if (!query) {
return li;
}
const escapedQuery = escapeRegExp(query);
const regexp = new RegExp(`>\\s*([^<]*?)(${escapedQuery})([^<]*)\\s*<`, 'ig');
return li.replace(regexp, (str, $1, $2, $3) => `> ${$1}<strong>${$2}</strong>${$3} <`);
};
export const defaultAutocompleteConfig = { export const defaultAutocompleteConfig = {
emojis: true, emojis: true,
members: true, members: true,
...@@ -664,16 +675,7 @@ class GfmAutoComplete { ...@@ -664,16 +675,7 @@ class GfmAutoComplete {
} }
return null; return null;
}, },
highlighter(li, query) { highlighter,
// override default behaviour to escape dot character
// see https://github.com/ichord/At.js/pull/576
if (!query) {
return li;
}
const escapedQuery = query.replace(/[.+]/, '\\$&');
const regexp = new RegExp(`>\\s*([^<]*?)(${escapedQuery})([^<]*)\\s*<`, 'ig');
return li.replace(regexp, (str, $1, $2, $3) => `> ${$1}<strong>${$2}</strong>${$3} <`);
},
}; };
} }
......
...@@ -8,7 +8,7 @@ import GfmAutoComplete from '~/gfm_auto_complete'; ...@@ -8,7 +8,7 @@ import GfmAutoComplete from '~/gfm_auto_complete';
* Some modules import `defaultAutocompleteConfig` or `membersBeforeSave` * Some modules import `defaultAutocompleteConfig` or `membersBeforeSave`
* which will be undefined if not exported from here in EE. * which will be undefined if not exported from here in EE.
*/ */
export { defaultAutocompleteConfig, membersBeforeSave } from '~/gfm_auto_complete'; export { defaultAutocompleteConfig, membersBeforeSave, highlighter } from '~/gfm_auto_complete';
class GfmAutoCompleteEE extends GfmAutoComplete { class GfmAutoCompleteEE extends GfmAutoComplete {
setupAtWho($input) { setupAtWho($input) {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery'; import $ from 'jquery';
import labelsFixture from 'test_fixtures/autocomplete_sources/labels.json'; import labelsFixture from 'test_fixtures/autocomplete_sources/labels.json';
import GfmAutoComplete, { membersBeforeSave } from 'ee_else_ce/gfm_auto_complete'; import GfmAutoComplete, { membersBeforeSave, highlighter } from 'ee_else_ce/gfm_auto_complete';
import { initEmojiMock } from 'helpers/emoji'; import { initEmojiMock } from 'helpers/emoji';
import '~/lib/utils/jquery_at_who'; import '~/lib/utils/jquery_at_who';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
...@@ -858,4 +858,14 @@ describe('GfmAutoComplete', () => { ...@@ -858,4 +858,14 @@ describe('GfmAutoComplete', () => {
); );
}); });
}); });
describe('highlighter', () => {
it('escapes regex', () => {
const li = '<li>couple (woman,woman) <gl-emoji data-name="couple_ww"></gl-emoji></li>';
expect(highlighter(li, ')')).toBe(
'<li> couple (woman,woman<strong>)</strong> <gl-emoji data-name="couple_ww"></gl-emoji></li>',
);
});
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment