[Snapshot and restore] Scape especial chars in snapshot searchbar (#208573)

Fixes https://github.com/elastic/kibana/issues/174039
This commit is contained in:
Sonia Sanz Vivas 2025-02-05 12:47:21 +01:00 committed by GitHub
parent 8d0f3544f1
commit f398ef877c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 74 additions and 5 deletions

View file

@ -11,5 +11,6 @@ export type { SortField, SortDirection, SnapshotListParams } from './snapshot_li
export {
getListParams,
getQueryFromListParams,
escapeString,
DEFAULT_SNAPSHOT_LIST_PARAMS,
} from './snapshot_list_params';

View file

@ -0,0 +1,52 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import {
DEFAULT_SNAPSHOT_LIST_PARAMS,
escapeString,
getQueryFromListParams,
} from './snapshot_list_params';
describe('Snapshot list params', () => {
describe('escapeString', () => {
it('should escape special characters', () => {
expect(escapeString('(special)[]{chars}')).toBe('\\(special\\)[]\\{chars\\}');
});
it('should unescape escaped characters before escape it ', () => {
expect(escapeString('\\(special\\)[]\\{chars\\}')).toBe('\\(special\\)[]\\{chars\\}');
});
it('should handle strings without special characters', () => {
expect(escapeString('no special chars')).toBe('no special chars');
});
});
describe('getQueryFromListParams', () => {
const schema = {};
it('should parse the query', () => {
const listParams = {
...DEFAULT_SNAPSHOT_LIST_PARAMS,
searchField: 'field',
searchValue: 'value',
};
expect(getQueryFromListParams(listParams, schema).text).toBe('field=value');
});
it('should parse the query and escape special characters', () => {
const listParams = {
...DEFAULT_SNAPSHOT_LIST_PARAMS,
searchField: 'field',
searchValue: '(val)ue',
};
expect(getQueryFromListParams(listParams, schema).text).toBe('field=\\(val\\)ue');
});
});
});

View file

@ -50,6 +50,12 @@ const resetSearchOptions = (listParams: SnapshotListParams): SnapshotListParams
searchOperator: undefined,
});
export const escapeString = (inputString: string) => {
return inputString.replace(/\\([{}()\\])|([{}()\\])/g, (match, unescaped, needsEscape) =>
unescaped ? match : `\\${needsEscape}`
);
};
// to init the query for repository and policyName search passed via url
export const getQueryFromListParams = (
listParams: SnapshotListParams,
@ -59,7 +65,8 @@ export const getQueryFromListParams = (
if (!searchField || !searchValue) {
return Query.MATCH_ALL;
}
return Query.parse(`${searchField}=${searchValue}`, { schema });
return Query.parse(`${searchField}=${escapeString(searchValue)}`, { schema });
};
export const getListParams = (listParams: SnapshotListParams, query: Query): SnapshotListParams => {

View file

@ -16,7 +16,12 @@ import { EuiSearchBarOnChangeArgs } from '@elastic/eui/src/components/search_bar
import { EuiButton, EuiCallOut, EuiSearchBar, EuiSpacer, Query } from '@elastic/eui';
import { SnapshotDeleteProvider } from '../../../../components';
import { SnapshotDetails } from '../../../../../../common/types';
import { getQueryFromListParams, SnapshotListParams, getListParams } from '../../../../lib';
import {
getQueryFromListParams,
SnapshotListParams,
getListParams,
escapeString,
} from '../../../../lib';
const SEARCH_DEBOUNCE_VALUE_MS = 200;
@ -117,6 +122,7 @@ export const SnapshotSearchBar: React.FunctionComponent<Props> = ({
})),
},
];
const reloadButton = (
<EuiButton color="success" iconType="refresh" onClick={reload} data-test-subj="reloadButton">
<FormattedMessage
@ -131,9 +137,10 @@ export const SnapshotSearchBar: React.FunctionComponent<Props> = ({
const onSearchBarChange = (args: EuiSearchBarOnChangeArgs) => {
const { query: changedQuery, error: queryError } = args;
if (queryError) {
setError(queryError);
} else if (changedQuery) {
if (changedQuery) {
changedQuery.text = escapeString(changedQuery.text);
setError(null);
setQuery(changedQuery);
if (changedQuery.ast.clauses.length > 1) {
@ -141,6 +148,8 @@ export const SnapshotSearchBar: React.FunctionComponent<Props> = ({
} else {
setCachedListParams(getListParams(listParams, changedQuery));
}
} else if (queryError) {
setError(queryError);
}
};