From b1473c2db92a4f9639a7c3ff04c45764e0a9b750 Mon Sep 17 00:00:00 2001 From: Paul Rosenzweig <paulrosenzweig@users.noreply.github.com> Date: Tue, 9 Jul 2019 17:56:50 -0400 Subject: [PATCH] add regexpEscape instead of deprecated RegExp.excape (#10277) --- .../components/database/MetadataSchemaList.jsx | 4 +++- .../components/database/MetadataTableList.jsx | 4 +++- frontend/src/metabase/lib/string.js | 14 ++++++++------ frontend/test/metabase/lib/string.unit.spec.js | 17 +++++++++++++++++ 4 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 frontend/test/metabase/lib/string.unit.spec.js diff --git a/frontend/src/metabase/admin/datamodel/components/database/MetadataSchemaList.jsx b/frontend/src/metabase/admin/datamodel/components/database/MetadataSchemaList.jsx index ad82e59f760..3b64300ac9a 100644 --- a/frontend/src/metabase/admin/datamodel/components/database/MetadataSchemaList.jsx +++ b/frontend/src/metabase/admin/datamodel/components/database/MetadataSchemaList.jsx @@ -6,6 +6,8 @@ import { t, ngettext, msgid } from "ttag"; import _ from "underscore"; import cx from "classnames"; +import { regexpEscape } from "metabase/lib/string"; + export default class MetadataSchemaList extends Component { constructor(props, context) { super(props, context); @@ -22,7 +24,7 @@ export default class MetadataSchemaList extends Component { this.setState({ searchText: event.target.value, searchRegex: event.target.value - ? new RegExp(RegExp.escape(event.target.value), "i") + ? new RegExp(regexpEscape(event.target.value), "i") : null, }); } diff --git a/frontend/src/metabase/admin/datamodel/components/database/MetadataTableList.jsx b/frontend/src/metabase/admin/datamodel/components/database/MetadataTableList.jsx index cf425503e00..0406cf43097 100644 --- a/frontend/src/metabase/admin/datamodel/components/database/MetadataTableList.jsx +++ b/frontend/src/metabase/admin/datamodel/components/database/MetadataTableList.jsx @@ -8,6 +8,8 @@ import { t, ngettext, msgid } from "ttag"; import _ from "underscore"; import cx from "classnames"; +import { regexpEscape } from "metabase/lib/string"; + export default class MetadataTableList extends Component { constructor(props, context) { super(props, context); @@ -30,7 +32,7 @@ export default class MetadataTableList extends Component { this.setState({ searchText: event.target.value, searchRegex: event.target.value - ? new RegExp(RegExp.escape(event.target.value), "i") + ? new RegExp(regexpEscape(event.target.value), "i") : null, }); } diff --git a/frontend/src/metabase/lib/string.js b/frontend/src/metabase/lib/string.js index 8fb1e7a7af7..d6b6fe78fe3 100644 --- a/frontend/src/metabase/lib/string.js +++ b/frontend/src/metabase/lib/string.js @@ -3,15 +3,17 @@ import _ from "underscore"; // Creates a regex that will find an order dependent, case insensitive substring. All whitespace will be rendered as ".*" in the regex, to create a fuzzy search. export function createMultiwordSearchRegex(input) { if (input) { - return new RegExp( - _.map(input.split(/\s+/), word => { - return RegExp.escape(word); - }).join(".*"), - "i", - ); + return new RegExp(_.map(input.split(/\s+/), regexpEscape).join(".*"), "i"); } } +// prefix special characters with "\" for creating a regex +export function regexpEscape(s) { + const regexpSpecialChars = /[\^\$\\\.\*\+\?\(\)\[\]\{\}\|]/g; + // "$&" in the replacement string is replaced with the matched string + return s.replace(regexpSpecialChars, "\\$&"); +} + export const countLines = str => str.split(/\n/g).length; export function caseInsensitiveSearch(haystack, needle) { diff --git a/frontend/test/metabase/lib/string.unit.spec.js b/frontend/test/metabase/lib/string.unit.spec.js new file mode 100644 index 00000000000..6632e327d42 --- /dev/null +++ b/frontend/test/metabase/lib/string.unit.spec.js @@ -0,0 +1,17 @@ +import { regexpEscape } from "metabase/lib/string"; + +describe("regexpEscape", () => { + const testCases = [ + ["nothing special here", "nothing special here"], + ["somewhat ./\\ special", "somewhat \\./\\\\ special"], + [ + "extra special ^$\\.*+?()[]{}|", + "extra special \\^\\$\\\\\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|", + ], + ]; + for (const [raw, escaped] of testCases) { + it(`should escape "${raw}" to "${escaped}"`, () => { + expect(regexpEscape(raw)).toEqual(escaped); + }); + } +}); -- GitLab