mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[kql] Fix toKqlExpression for quoted values with escaped quotes (#162599)
## Summary `toKqlExpression` support was added in https://github.com/elastic/kibana/pull/161601. This PR Fixes a bug with `toKqlExpression` that did not properly re-escape quotes inside of quoted values. Without this fix, calling `toKqlExpression` on the AST generated from a KQL expression like `my_field: "quoted \"value\""` would result in a string like `my_field: "quoted "value""` instead of the original expression. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
This commit is contained in:
parent
a1be0029c3
commit
e8978ee630
10 changed files with 39 additions and 48 deletions
|
@ -116,6 +116,7 @@ export {
|
|||
nodeTypes,
|
||||
toElasticsearchQuery,
|
||||
escapeKuery,
|
||||
escapeQuotes,
|
||||
} from './src/kuery';
|
||||
|
||||
export {
|
||||
|
|
|
@ -23,5 +23,5 @@ export const toElasticsearchQuery = (...params: Parameters<typeof astToElasticse
|
|||
export { KQLSyntaxError } from './kuery_syntax_error';
|
||||
export { nodeTypes, nodeBuilder } from './node_types';
|
||||
export { fromKueryExpression, toKqlExpression } from './ast';
|
||||
export { escapeKuery } from './utils';
|
||||
export { escapeKuery, escapeQuotes } from './utils';
|
||||
export type { DslQuery, KueryNode, KueryQueryOptions, KueryParseOptions } from './types';
|
||||
|
|
|
@ -31,13 +31,13 @@ describe('kuery node types', () => {
|
|||
});
|
||||
|
||||
describe('toKqlExpression', () => {
|
||||
test('quoted', () => {
|
||||
test('unquoted', () => {
|
||||
const node = buildNode('foo');
|
||||
const result = toKqlExpression(node);
|
||||
expect(result).toBe('foo');
|
||||
});
|
||||
|
||||
test('unquoted', () => {
|
||||
test('quoted', () => {
|
||||
const node = buildNode('foo', true);
|
||||
const result = toKqlExpression(node);
|
||||
expect(result).toBe('"foo"');
|
||||
|
@ -54,6 +54,12 @@ describe('kuery node types', () => {
|
|||
const result = toKqlExpression(node);
|
||||
expect(result).toBe('foo \\and bar \\not baz \\or qux');
|
||||
});
|
||||
|
||||
test('quoted with escaped quotes', () => {
|
||||
const node = buildNode(`I said, "Hello."`, true);
|
||||
const result = toKqlExpression(node);
|
||||
expect(result).toBe(`"I said, \\"Hello.\\""`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { type KueryNode, escapeKuery } from '..';
|
||||
import { type KueryNode, escapeKuery, escapeQuotes } from '..';
|
||||
|
||||
export const KQL_NODE_TYPE_LITERAL = 'literal';
|
||||
|
||||
|
@ -35,5 +35,5 @@ export function toElasticsearchQuery(node: KqlLiteralNode) {
|
|||
}
|
||||
|
||||
export function toKqlExpression(node: KqlLiteralNode): string {
|
||||
return node.isQuoted ? `"${node.value}"` : escapeKuery(`${node.value}`);
|
||||
return node.isQuoted ? `"${escapeQuotes(`${node.value}`)}"` : escapeKuery(`${node.value}`);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,23 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { escapeKuery } from './escape_kuery';
|
||||
import { escapeKuery, escapeQuotes } from './escape_kuery';
|
||||
|
||||
describe('escapeQuotes', () => {
|
||||
test('should escape quotes', () => {
|
||||
const value = 'I said, "Hello."';
|
||||
const expected = 'I said, \\"Hello.\\"';
|
||||
|
||||
expect(escapeQuotes(value)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should escape backslashes and quotes', () => {
|
||||
const value = 'Backslashes \\" in the middle and ends with quotes \\"';
|
||||
const expected = 'Backslashes \\\\\\" in the middle and ends with quotes \\\\\\"';
|
||||
|
||||
expect(escapeQuotes(value)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('escapeKuery', () => {
|
||||
test('should escape special characters', () => {
|
||||
|
|
|
@ -8,6 +8,14 @@
|
|||
|
||||
import { flow } from 'lodash';
|
||||
|
||||
/**
|
||||
* Escapes backslashes and double-quotes. (Useful when putting a string in quotes to use as a value
|
||||
* in a KQL expression. See the QuotedCharacter rule in kuery.peg.)
|
||||
*/
|
||||
export function escapeQuotes(str: string) {
|
||||
return str.replace(/[\\"]/g, '\\$&');
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a Kuery node value to ensure that special characters, operators, and whitespace do not result in a parsing error or unintended
|
||||
* behavior when using the value as an argument for the `buildNode` function.
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { escapeKuery } from './escape_kuery';
|
||||
export { escapeKuery, escapeQuotes } from './escape_kuery';
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { escapeQuotes } from './escape_kuery';
|
||||
|
||||
describe('Kuery escape', () => {
|
||||
test('should escape quotes', () => {
|
||||
const value = 'I said, "Hello."';
|
||||
const expected = 'I said, \\"Hello.\\"';
|
||||
|
||||
expect(escapeQuotes(value)).toBe(expected);
|
||||
});
|
||||
|
||||
test('should escape backslashes and quotes', () => {
|
||||
const value = 'Backslashes \\" in the middle and ends with quotes \\"';
|
||||
const expected = 'Backslashes \\\\\\" in the middle and ends with quotes \\\\\\"';
|
||||
|
||||
expect(escapeQuotes(value)).toBe(expected);
|
||||
});
|
||||
});
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Escapes backslashes and double-quotes. (Useful when putting a string in quotes to use as a value
|
||||
* in a KQL expression. See the QuotedCharacter rule in kuery.peg.)
|
||||
*/
|
||||
export function escapeQuotes(str: string) {
|
||||
return str.replace(/[\\"]/g, '\\$&');
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
import { flatten } from 'lodash';
|
||||
import { CoreSetup } from '@kbn/core/public';
|
||||
import type { DataView, DataViewField } from '@kbn/data-views-plugin/common';
|
||||
import { escapeQuotes } from './lib/escape_kuery';
|
||||
import { escapeQuotes } from '@kbn/es-query';
|
||||
import { KqlQuerySuggestionProvider } from './types';
|
||||
import type { UnifiedSearchPublicPluginStart } from '../../../types';
|
||||
import { QuerySuggestion, QuerySuggestionTypes } from '../query_suggestion_provider';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue