diff --git a/redisinsight/ui/src/utils/monaco/monacoRedisMonarchTokensProvider.ts b/redisinsight/ui/src/utils/monaco/monacoRedisMonarchTokensProvider.ts index 44f342766e..68eef4c6db 100644 --- a/redisinsight/ui/src/utils/monaco/monacoRedisMonarchTokensProvider.ts +++ b/redisinsight/ui/src/utils/monaco/monacoRedisMonarchTokensProvider.ts @@ -5,6 +5,8 @@ import { IRedisCommand } from 'uiSrc/constants' const STRING_DOUBLE = 'string.double' +const escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + export const getRedisMonarchTokensProvider = ( commands: IRedisCommand[], ): monacoEditor.languages.IMonarchLanguage => { @@ -12,8 +14,8 @@ export const getRedisMonarchTokensProvider = ( const searchCommands = remove(commandRedisCommands, ({ token }) => token?.startsWith(ModuleCommandPrefix.RediSearch), ) - const COMMON_COMMANDS_REGEX = `^\\s*(\\d+\\s+)?(${commandRedisCommands.map(({ token }) => token).join('|')})\\b` - const SEARCH_COMMANDS_REGEX = `^\\s*(\\d+\\s+)?(${searchCommands.map(({ token }) => token).join('|')})\\b` + const COMMON_COMMANDS_REGEX = `^\\s*(\\d+\\s+)?(${commandRedisCommands.map(({ token }) => escapeRegex(token || '')).join('|')})\\b` + const SEARCH_COMMANDS_REGEX = `^\\s*(\\d+\\s+)?(${searchCommands.map(({ token }) => escapeRegex(token || '')).join('|')})\\b` return { defaultToken: '', diff --git a/redisinsight/ui/src/utils/monaco/monarchTokens/redisearchTokensTemplates.ts b/redisinsight/ui/src/utils/monaco/monarchTokens/redisearchTokensTemplates.ts index e2311ee5ba..538c8c8b12 100644 --- a/redisinsight/ui/src/utils/monaco/monarchTokens/redisearchTokensTemplates.ts +++ b/redisinsight/ui/src/utils/monaco/monarchTokens/redisearchTokensTemplates.ts @@ -3,6 +3,9 @@ import { curryRight } from 'lodash' import { Maybe } from 'uiSrc/utils' import { IRedisCommand } from 'uiSrc/constants' +// Escape special regex characters in tokens +const escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + const appendToken = (token: string, name: Maybe) => name ? `${token}.${name}` : token export const generateQuery = ( @@ -17,7 +20,7 @@ export const generateQuery = ( ): languages.IMonarchLanguageRule => args?.length ? [ - `(${args?.map(({ token }) => token).join('|')})\\b`, + `(${args?.map(({ token }) => escapeRegex(token || '')).join('|')})\\b`, { token: 'function', next: appendTokenName(tokenName) }, ] : [/_/, ''] diff --git a/redisinsight/ui/src/utils/monaco/redisearch/utils.ts b/redisinsight/ui/src/utils/monaco/redisearch/utils.ts index b7419fcadf..6a1d9164de 100644 --- a/redisinsight/ui/src/utils/monaco/redisearch/utils.ts +++ b/redisinsight/ui/src/utils/monaco/redisearch/utils.ts @@ -5,6 +5,8 @@ import { generateQuery } from 'uiSrc/utils/monaco/monarchTokens/redisearchTokens import { ICommandTokenType, IRedisCommand } from 'uiSrc/constants' import { DefinedArgumentName } from 'uiSrc/pages/workbench/constants' +const escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + export const generateKeywords = (commands: IRedisCommand[]) => commands.map(({ name }) => name) export const generateTokens = ( @@ -153,7 +155,7 @@ export const getBlockTokens = ( if (tokensWithNextExpression.length) { result.push([ - `(${tokensWithNextExpression.map(({ token }) => token).join('|')})\\b`, + `(${tokensWithNextExpression.map(({ token }) => escapeRegex(token || '')).join('|')})\\b`, { token: `argument.block.${lvl}.${name}`, next: '@query', @@ -163,7 +165,7 @@ export const getBlockTokens = ( if (restTokens.length) { result.push([ - `(${restTokens.map(({ token }) => token).join('|')})\\b`, + `(${restTokens.map(({ token }) => escapeRegex(token || '')).join('|')})\\b`, { token: `argument.block.${lvl}.${name}`, next: '@root' }, ]) }