From 6c621bf65bddea4a7a956457f277b628c0192fa3 Mon Sep 17 00:00:00 2001 From: sjaanus Date: Wed, 28 Dec 2022 12:35:27 +0200 Subject: [PATCH] Fix crashing search bars (#2765) --- .../application/ApplicationList/ApplicationList.tsx | 3 ++- frontend/src/component/common/Highlighter/Highlighter.tsx | 5 ++--- frontend/src/component/project/ProjectList/ProjectList.tsx | 3 ++- frontend/src/hooks/useFeaturesFilter.ts | 3 ++- src/lib/proxy/create-context.test.ts | 2 -- src/lib/util/escape-regex.ts | 3 +++ 6 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 src/lib/util/escape-regex.ts diff --git a/frontend/src/component/application/ApplicationList/ApplicationList.tsx b/frontend/src/component/application/ApplicationList/ApplicationList.tsx index adc483ec77..eb27245f0a 100644 --- a/frontend/src/component/application/ApplicationList/ApplicationList.tsx +++ b/frontend/src/component/application/ApplicationList/ApplicationList.tsx @@ -8,6 +8,7 @@ import useApplications from 'hooks/api/getters/useApplications/useApplications'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { useSearchParams } from 'react-router-dom'; import { Search } from 'component/common/Search/Search'; +import { safeRegExp } from '@server/util/escape-regex'; type PageQueryType = Partial>; @@ -30,7 +31,7 @@ export const ApplicationList = () => { }, [searchValue, setSearchParams]); const filteredApplications = useMemo(() => { - const regExp = new RegExp(searchValue, 'i'); + const regExp = safeRegExp(searchValue, 'i'); return searchValue ? applications?.filter(a => regExp.test(a.appName)) : applications; diff --git a/frontend/src/component/common/Highlighter/Highlighter.tsx b/frontend/src/component/common/Highlighter/Highlighter.tsx index fa5f47815f..c08582df0d 100644 --- a/frontend/src/component/common/Highlighter/Highlighter.tsx +++ b/frontend/src/component/common/Highlighter/Highlighter.tsx @@ -1,5 +1,6 @@ import { VFC } from 'react'; import { useStyles } from './Highlighter.styles'; +import { safeRegExp } from '@server/util/escape-regex'; interface IHighlighterProps { search?: string; @@ -7,8 +8,6 @@ interface IHighlighterProps { caseSensitive?: boolean; } -const escapeRegex = (str: string) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - export const Highlighter: VFC = ({ search, children, @@ -23,7 +22,7 @@ export const Highlighter: VFC = ({ return <>{children}; } - const regex = new RegExp(escapeRegex(search), caseSensitive ? 'g' : 'gi'); + const regex = safeRegExp(search, caseSensitive ? 'g' : 'gi'); return ( >; @@ -93,7 +94,7 @@ export const ProjectListNew = () => { }, [searchValue, setSearchParams]); const filteredProjects = useMemo(() => { - const regExp = new RegExp(searchValue, 'i'); + const regExp = safeRegExp(searchValue, 'i'); return ( searchValue ? projects.filter(project => regExp.test(project.name)) diff --git a/frontend/src/hooks/useFeaturesFilter.ts b/frontend/src/hooks/useFeaturesFilter.ts index 6a92b6395a..cb76b2cf75 100644 --- a/frontend/src/hooks/useFeaturesFilter.ts +++ b/frontend/src/hooks/useFeaturesFilter.ts @@ -1,6 +1,7 @@ import React, { useMemo } from 'react'; import { createGlobalStateHook } from 'hooks/useGlobalState'; import { FeatureSchema } from 'openapi'; +import { safeRegExp } from '@server/util/escape-regex'; export interface IFeaturesFilter { query?: string; @@ -66,7 +67,7 @@ const filterFeaturesByQuery = ( // Try to parse the search query as a RegExp. // Return all features if it can't be parsed. try { - const regExp = new RegExp(filter.query, 'i'); + const regExp = safeRegExp(filter.query, 'i'); return features.filter(f => filterFeatureByRegExp(f, filter, regExp)); } catch (err) { if (err instanceof SyntaxError) { diff --git a/src/lib/proxy/create-context.test.ts b/src/lib/proxy/create-context.test.ts index 8ba87dbbf7..bdbd440e10 100644 --- a/src/lib/proxy/create-context.test.ts +++ b/src/lib/proxy/create-context.test.ts @@ -107,8 +107,6 @@ test.skip('will not blow up if userId is an array', () => { properties: ['some'], }); - // console.log(context); - expect(context.userId).toBe('123'); expect(context).not.toHaveProperty('tenantId'); expect(context).not.toHaveProperty('region'); diff --git a/src/lib/util/escape-regex.ts b/src/lib/util/escape-regex.ts new file mode 100644 index 0000000000..d599dc8dfe --- /dev/null +++ b/src/lib/util/escape-regex.ts @@ -0,0 +1,3 @@ +export function safeRegExp(pattern: string, flags?: string): RegExp { + return new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), flags); +}