Escape server name when used inside regex (#2449)

* Escape server name when used inside regex

* Move util under common and add test
This commit is contained in:
Tasos Boulis
2022-12-06 17:29:02 +02:00
committed by GitHub
parent 865fd2522f
commit de65cfca4e
3 changed files with 20 additions and 2 deletions

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import Utils from 'common/utils/util'; import Utils, {escapeRegex} from 'common/utils/util';
describe('common/utils/util', () => { describe('common/utils/util', () => {
describe('shorten', () => { describe('shorten', () => {
@@ -115,4 +115,12 @@ describe('common/utils/util', () => {
expect(Utils.boundsDiff(base, actual)).toEqual(diff); expect(Utils.boundsDiff(base, actual)).toEqual(diff);
}); });
}); });
describe('escapeRegex', () => {
it('should escape special chars in string when used inside regex', () => {
const str = 'Language C++';
const regex = `${escapeRegex(str)}___TAB_[A-Z]+`;
expect(new RegExp(regex).test('Language C++___TAB_ABCDEF')).toBe(true);
});
});
}); });

View File

@@ -58,9 +58,18 @@ function boundsDiff(base: Rectangle, actual: Rectangle) {
}; };
} }
// MM-48463 - https://stackoverflow.com/a/3561711/5605822
export const escapeRegex = (s?: string) => {
if (typeof s !== 'string') {
return '';
}
return s.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&');
};
export default { export default {
runMode, runMode,
shorten, shorten,
isVersionGreaterThanOrEqualTo, isVersionGreaterThanOrEqualTo,
boundsDiff, boundsDiff,
escapeRegex,
}; };

View File

@@ -14,6 +14,7 @@ import {TeamWithTabs} from 'types/config';
import {DownloadedItems} from 'types/downloads'; import {DownloadedItems} from 'types/downloads';
import {getTabViewName} from 'common/tabs/TabView'; import {getTabViewName} from 'common/tabs/TabView';
import {escapeRegex} from 'common/utils/util';
import restoreButton from '../../assets/titlebar/chrome-restore.svg'; import restoreButton from '../../assets/titlebar/chrome-restore.svg';
import maximizeButton from '../../assets/titlebar/chrome-maximize.svg'; import maximizeButton from '../../assets/titlebar/chrome-maximize.svg';
@@ -462,7 +463,7 @@ class MainPage extends React.PureComponent<Props, State> {
); );
} }
const serverMatch = `${this.state.activeServerName}___TAB_[A-Z]+`; const serverMatch = `${escapeRegex(this.state.activeServerName)}___TAB_[A-Z]+`;
const totalMentionCount = Object.keys(this.state.mentionCounts).reduce((sum, key) => { const totalMentionCount = Object.keys(this.state.mentionCounts).reduce((sum, key) => {
// Strip out current server from unread and mention counts // Strip out current server from unread and mention counts
if (this.state.activeServerName && key.match(serverMatch)) { if (this.state.activeServerName && key.match(serverMatch)) {