Commit e2ea2c49 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'ph/343358/escapeRegex' into 'master'

Correctly escape regex in GFM autocomplete

See merge request gitlab-org/gitlab!72688
parents dbe47283 25ec18e3
import $ from 'jquery';
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 axios from '~/lib/utils/axios_utils';
import { s__, __, sprintf } from '~/locale';
......@@ -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 = {
emojis: true,
members: true,
......@@ -664,16 +675,7 @@ class GfmAutoComplete {
}
return null;
},
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 = query.replace(/[.+]/, '\\$&');
const regexp = new RegExp(`>\\s*([^<]*?)(${escapedQuery})([^<]*)\\s*<`, 'ig');
return li.replace(regexp, (str, $1, $2, $3) => `> ${$1}<strong>${$2}</strong>${$3} <`);
},
highlighter,
};
}
......
......@@ -8,7 +8,7 @@ import GfmAutoComplete from '~/gfm_auto_complete';
* Some modules import `defaultAutocompleteConfig` or `membersBeforeSave`
* 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 {
setupAtWho($input) {
......
......@@ -2,7 +2,7 @@
import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery';
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 '~/lib/utils/jquery_at_who';
import { TEST_HOST } from 'helpers/test_constants';
......@@ -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