[kql] Fix literal toKqlExpression to escape special characters and keywords (#162195)

## Summary

`toKqlExpression` support was added in
https://github.com/elastic/kibana/pull/161601. This PR Fixes a bug with
`toKqlExpression` that did not properly escape special characters and
keywords.

Without this fix, you could get into a problematic situation like the
following:

```ts
const node = fromKueryExpression('field: bar\\*');
const result = toKqlExpression(node); // 'field: bar*'
```

This was incorrect, since if we were then to call `fromKueryExpression`
on this value again, we would get a wildcard (`bar*`), not a string.

### 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:
Lukas Olson 2023-07-20 13:15:45 -07:00 committed by GitHub
parent 1d5945aa90
commit 8ca815aaa3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 4 deletions

View file

@ -356,7 +356,7 @@ describe('kuery functions', () => {
expect(result).toMatchInlineSnapshot(`"byt* > 1000"`);
});
test('with wildcard field & wildcard value', () => {
test('with wildcard field & value', () => {
const node = nodeTypes.function.buildNode(
'range',
'byt*',
@ -364,7 +364,7 @@ describe('kuery functions', () => {
'100*'
) as KqlRangeFunctionNode;
const result = range.toKqlExpression(node);
expect(result).toMatchInlineSnapshot(`"byt* > 100*"`);
expect(result).toMatchInlineSnapshot(`"byt* > 100\\\\*"`);
});
});
});

View file

@ -42,6 +42,18 @@ describe('kuery node types', () => {
const result = toKqlExpression(node);
expect(result).toBe('"foo"');
});
test('reserved chars', () => {
const node = buildNode('():<>"*');
const result = toKqlExpression(node);
expect(result).toBe('\\(\\)\\:\\<\\>\\"\\*');
});
test('reserved keywords', () => {
const node = buildNode('foo and bar not baz or qux');
const result = toKqlExpression(node);
expect(result).toBe('foo \\and bar \\not baz \\or qux');
});
});
});
});

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import type { KueryNode } from '../types';
import { type KueryNode, escapeKuery } 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}"` : `${node.value}`;
return node.isQuoted ? `"${node.value}"` : escapeKuery(`${node.value}`);
}