mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
* [kuery] support matching field names with newlines (#29539) * [kuery] support matching field names with newlines * Add support for newlines in KQL grammar * Add test for newlines in wildcards * Fix test * Use 's' instead of 'm' to match newlines instead of doing multi-line * Fix autocomplete suggestions to handle newlines and tabs in field names * Add line feed to escaped whitespace * Fix broken test
This commit is contained in:
parent
4649cceeab
commit
6d02863c33
7 changed files with 221 additions and 128 deletions
|
@ -203,27 +203,35 @@ module.exports = (function() {
|
|||
peg$c39 = "*",
|
||||
peg$c40 = { type: "literal", value: "*", description: "\"*\"" },
|
||||
peg$c41 = function() { return wildcardSymbol; },
|
||||
peg$c42 = function(keyword) { return keyword; },
|
||||
peg$c43 = /^[\\():<>"*]/,
|
||||
peg$c44 = { type: "class", value: "[\\\\():<>\"*]", description: "[\\\\():<>\"*]" },
|
||||
peg$c45 = "<=",
|
||||
peg$c46 = { type: "literal", value: "<=", description: "\"<=\"" },
|
||||
peg$c47 = function() { return 'lte'; },
|
||||
peg$c48 = ">=",
|
||||
peg$c49 = { type: "literal", value: ">=", description: "\">=\"" },
|
||||
peg$c50 = function() { return 'gte'; },
|
||||
peg$c51 = "<",
|
||||
peg$c52 = { type: "literal", value: "<", description: "\"<\"" },
|
||||
peg$c53 = function() { return 'lt'; },
|
||||
peg$c54 = ">",
|
||||
peg$c55 = { type: "literal", value: ">", description: "\">\"" },
|
||||
peg$c56 = function() { return 'gt'; },
|
||||
peg$c57 = /^[ \t\r\n]/,
|
||||
peg$c58 = { type: "class", value: "[\\ \\t\\r\\n]", description: "[\\ \\t\\r\\n]" },
|
||||
peg$c59 = function() { return parseCursor; },
|
||||
peg$c60 = "@kuery-cursor@",
|
||||
peg$c61 = { type: "literal", value: "@kuery-cursor@", description: "\"@kuery-cursor@\"" },
|
||||
peg$c62 = function() { return cursorSymbol; },
|
||||
peg$c42 = "\\t",
|
||||
peg$c43 = { type: "literal", value: "\\t", description: "\"\\\\t\"" },
|
||||
peg$c44 = function() { return '\t'; },
|
||||
peg$c45 = "\\r",
|
||||
peg$c46 = { type: "literal", value: "\\r", description: "\"\\\\r\"" },
|
||||
peg$c47 = "\\n",
|
||||
peg$c48 = { type: "literal", value: "\\n", description: "\"\\\\n\"" },
|
||||
peg$c49 = function() { return '\n'; },
|
||||
peg$c50 = function(keyword) { return keyword; },
|
||||
peg$c51 = /^[\\():<>"*]/,
|
||||
peg$c52 = { type: "class", value: "[\\\\():<>\"*]", description: "[\\\\():<>\"*]" },
|
||||
peg$c53 = "<=",
|
||||
peg$c54 = { type: "literal", value: "<=", description: "\"<=\"" },
|
||||
peg$c55 = function() { return 'lte'; },
|
||||
peg$c56 = ">=",
|
||||
peg$c57 = { type: "literal", value: ">=", description: "\">=\"" },
|
||||
peg$c58 = function() { return 'gte'; },
|
||||
peg$c59 = "<",
|
||||
peg$c60 = { type: "literal", value: "<", description: "\"<\"" },
|
||||
peg$c61 = function() { return 'lt'; },
|
||||
peg$c62 = ">",
|
||||
peg$c63 = { type: "literal", value: ">", description: "\">\"" },
|
||||
peg$c64 = function() { return 'gt'; },
|
||||
peg$c65 = /^[ \t\r\n]/,
|
||||
peg$c66 = { type: "class", value: "[\\ \\t\\r\\n]", description: "[\\ \\t\\r\\n]" },
|
||||
peg$c67 = function() { return parseCursor; },
|
||||
peg$c68 = "@kuery-cursor@",
|
||||
peg$c69 = { type: "literal", value: "@kuery-cursor@", description: "\"@kuery-cursor@\"" },
|
||||
peg$c70 = function() { return cursorSymbol; },
|
||||
|
||||
peg$currPos = 0,
|
||||
peg$savedPos = 0,
|
||||
|
@ -1170,53 +1178,23 @@ module.exports = (function() {
|
|||
function peg$parseQuotedCharacter() {
|
||||
var s0, s1, s2;
|
||||
|
||||
s0 = peg$currPos;
|
||||
if (input.charCodeAt(peg$currPos) === 92) {
|
||||
s1 = peg$c30;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c31); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
if (peg$c32.test(input.charAt(peg$currPos))) {
|
||||
s2 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c33); }
|
||||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c34(s2);
|
||||
s0 = s1;
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
s0 = peg$parseEscapedWhitespace();
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
s1 = peg$currPos;
|
||||
peg$silentFails++;
|
||||
s2 = peg$parseCursor();
|
||||
peg$silentFails--;
|
||||
if (s2 === peg$FAILED) {
|
||||
s1 = void 0;
|
||||
if (input.charCodeAt(peg$currPos) === 92) {
|
||||
s1 = peg$c30;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c31); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
if (peg$c35.test(input.charAt(peg$currPos))) {
|
||||
if (peg$c32.test(input.charAt(peg$currPos))) {
|
||||
s2 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c36); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c33); }
|
||||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
|
@ -1230,6 +1208,39 @@ module.exports = (function() {
|
|||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
s1 = peg$currPos;
|
||||
peg$silentFails++;
|
||||
s2 = peg$parseCursor();
|
||||
peg$silentFails--;
|
||||
if (s2 === peg$FAILED) {
|
||||
s1 = void 0;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
if (peg$c35.test(input.charAt(peg$currPos))) {
|
||||
s2 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c36); }
|
||||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c34(s2);
|
||||
s0 = s1;
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s0;
|
||||
|
@ -1295,57 +1306,63 @@ module.exports = (function() {
|
|||
function peg$parseUnquotedCharacter() {
|
||||
var s0, s1, s2, s3, s4;
|
||||
|
||||
s0 = peg$parseEscapedSpecialCharacter();
|
||||
s0 = peg$parseEscapedWhitespace();
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$parseEscapedKeyword();
|
||||
s0 = peg$parseEscapedSpecialCharacter();
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$parseWildcard();
|
||||
s0 = peg$parseEscapedKeyword();
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
s1 = peg$currPos;
|
||||
peg$silentFails++;
|
||||
s2 = peg$parseSpecialCharacter();
|
||||
peg$silentFails--;
|
||||
if (s2 === peg$FAILED) {
|
||||
s1 = void 0;
|
||||
} else {
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
s2 = peg$currPos;
|
||||
s0 = peg$parseWildcard();
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
s1 = peg$currPos;
|
||||
peg$silentFails++;
|
||||
s3 = peg$parseKeyword();
|
||||
s2 = peg$parseSpecialCharacter();
|
||||
peg$silentFails--;
|
||||
if (s3 === peg$FAILED) {
|
||||
s2 = void 0;
|
||||
if (s2 === peg$FAILED) {
|
||||
s1 = void 0;
|
||||
} else {
|
||||
peg$currPos = s2;
|
||||
s2 = peg$FAILED;
|
||||
peg$currPos = s1;
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
s3 = peg$currPos;
|
||||
if (s1 !== peg$FAILED) {
|
||||
s2 = peg$currPos;
|
||||
peg$silentFails++;
|
||||
s4 = peg$parseCursor();
|
||||
s3 = peg$parseKeyword();
|
||||
peg$silentFails--;
|
||||
if (s4 === peg$FAILED) {
|
||||
s3 = void 0;
|
||||
if (s3 === peg$FAILED) {
|
||||
s2 = void 0;
|
||||
} else {
|
||||
peg$currPos = s3;
|
||||
s3 = peg$FAILED;
|
||||
peg$currPos = s2;
|
||||
s2 = peg$FAILED;
|
||||
}
|
||||
if (s3 !== peg$FAILED) {
|
||||
if (input.length > peg$currPos) {
|
||||
s4 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
if (s2 !== peg$FAILED) {
|
||||
s3 = peg$currPos;
|
||||
peg$silentFails++;
|
||||
s4 = peg$parseCursor();
|
||||
peg$silentFails--;
|
||||
if (s4 === peg$FAILED) {
|
||||
s3 = void 0;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c38); }
|
||||
peg$currPos = s3;
|
||||
s3 = peg$FAILED;
|
||||
}
|
||||
if (s4 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c34(s4);
|
||||
s0 = s1;
|
||||
if (s3 !== peg$FAILED) {
|
||||
if (input.length > peg$currPos) {
|
||||
s4 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s4 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c38); }
|
||||
}
|
||||
if (s4 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c34(s4);
|
||||
s0 = s1;
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
|
@ -1358,9 +1375,6 @@ module.exports = (function() {
|
|||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1436,6 +1450,56 @@ module.exports = (function() {
|
|||
return s0;
|
||||
}
|
||||
|
||||
function peg$parseEscapedWhitespace() {
|
||||
var s0, s1;
|
||||
|
||||
s0 = peg$currPos;
|
||||
if (input.substr(peg$currPos, 2) === peg$c42) {
|
||||
s1 = peg$c42;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c43); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c44();
|
||||
}
|
||||
s0 = s1;
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
if (input.substr(peg$currPos, 2) === peg$c45) {
|
||||
s1 = peg$c45;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c46); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c44();
|
||||
}
|
||||
s0 = s1;
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
if (input.substr(peg$currPos, 2) === peg$c47) {
|
||||
s1 = peg$c47;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c48); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c49();
|
||||
}
|
||||
s0 = s1;
|
||||
}
|
||||
}
|
||||
|
||||
return s0;
|
||||
}
|
||||
|
||||
function peg$parseEscapedSpecialCharacter() {
|
||||
var s0, s1, s2;
|
||||
|
||||
|
@ -1504,7 +1568,7 @@ module.exports = (function() {
|
|||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c42(s2);
|
||||
s1 = peg$c50(s2);
|
||||
s0 = s1;
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
|
@ -1535,12 +1599,12 @@ module.exports = (function() {
|
|||
function peg$parseSpecialCharacter() {
|
||||
var s0;
|
||||
|
||||
if (peg$c43.test(input.charAt(peg$currPos))) {
|
||||
if (peg$c51.test(input.charAt(peg$currPos))) {
|
||||
s0 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s0 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c44); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c52); }
|
||||
}
|
||||
|
||||
return s0;
|
||||
|
@ -1550,58 +1614,58 @@ module.exports = (function() {
|
|||
var s0, s1;
|
||||
|
||||
s0 = peg$currPos;
|
||||
if (input.substr(peg$currPos, 2) === peg$c45) {
|
||||
s1 = peg$c45;
|
||||
if (input.substr(peg$currPos, 2) === peg$c53) {
|
||||
s1 = peg$c53;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c46); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c54); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c47();
|
||||
s1 = peg$c55();
|
||||
}
|
||||
s0 = s1;
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
if (input.substr(peg$currPos, 2) === peg$c48) {
|
||||
s1 = peg$c48;
|
||||
if (input.substr(peg$currPos, 2) === peg$c56) {
|
||||
s1 = peg$c56;
|
||||
peg$currPos += 2;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c49); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c57); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c50();
|
||||
s1 = peg$c58();
|
||||
}
|
||||
s0 = s1;
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
if (input.charCodeAt(peg$currPos) === 60) {
|
||||
s1 = peg$c51;
|
||||
s1 = peg$c59;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c52); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c60); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c53();
|
||||
s1 = peg$c61();
|
||||
}
|
||||
s0 = s1;
|
||||
if (s0 === peg$FAILED) {
|
||||
s0 = peg$currPos;
|
||||
if (input.charCodeAt(peg$currPos) === 62) {
|
||||
s1 = peg$c54;
|
||||
s1 = peg$c62;
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c55); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c63); }
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c56();
|
||||
s1 = peg$c64();
|
||||
}
|
||||
s0 = s1;
|
||||
}
|
||||
|
@ -1614,12 +1678,12 @@ module.exports = (function() {
|
|||
function peg$parseSpace() {
|
||||
var s0;
|
||||
|
||||
if (peg$c57.test(input.charAt(peg$currPos))) {
|
||||
if (peg$c65.test(input.charAt(peg$currPos))) {
|
||||
s0 = input.charAt(peg$currPos);
|
||||
peg$currPos++;
|
||||
} else {
|
||||
s0 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c58); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c66); }
|
||||
}
|
||||
|
||||
return s0;
|
||||
|
@ -1630,23 +1694,23 @@ module.exports = (function() {
|
|||
|
||||
s0 = peg$currPos;
|
||||
peg$savedPos = peg$currPos;
|
||||
s1 = peg$c59();
|
||||
s1 = peg$c67();
|
||||
if (s1) {
|
||||
s1 = void 0;
|
||||
} else {
|
||||
s1 = peg$FAILED;
|
||||
}
|
||||
if (s1 !== peg$FAILED) {
|
||||
if (input.substr(peg$currPos, 14) === peg$c60) {
|
||||
s2 = peg$c60;
|
||||
if (input.substr(peg$currPos, 14) === peg$c68) {
|
||||
s2 = peg$c68;
|
||||
peg$currPos += 14;
|
||||
} else {
|
||||
s2 = peg$FAILED;
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c61); }
|
||||
if (peg$silentFails === 0) { peg$fail(peg$c69); }
|
||||
}
|
||||
if (s2 !== peg$FAILED) {
|
||||
peg$savedPos = s0;
|
||||
s1 = peg$c62();
|
||||
s1 = peg$c70();
|
||||
s0 = s1;
|
||||
} else {
|
||||
peg$currPos = s0;
|
||||
|
|
|
@ -199,7 +199,8 @@ QuotedString
|
|||
}
|
||||
|
||||
QuotedCharacter
|
||||
= '\\' char:[\\"] { return char; }
|
||||
= EscapedWhitespace
|
||||
/ '\\' char:[\\"] { return char; }
|
||||
/ !Cursor char:[^"] { return char; }
|
||||
|
||||
UnquotedLiteral
|
||||
|
@ -226,7 +227,8 @@ UnquotedLiteral
|
|||
}
|
||||
|
||||
UnquotedCharacter
|
||||
= EscapedSpecialCharacter
|
||||
= EscapedWhitespace
|
||||
/ EscapedSpecialCharacter
|
||||
/ EscapedKeyword
|
||||
/ Wildcard
|
||||
/ !SpecialCharacter !Keyword !Cursor char:. { return char; }
|
||||
|
@ -248,6 +250,11 @@ OptionalSpace
|
|||
}
|
||||
/ Space*
|
||||
|
||||
EscapedWhitespace
|
||||
= '\\t' { return '\t'; }
|
||||
/ '\\r' { return '\t'; }
|
||||
/ '\\n' { return '\n'; }
|
||||
|
||||
EscapedSpecialCharacter
|
||||
= '\\' char:SpecialCharacter { return char; }
|
||||
|
||||
|
|
|
@ -79,6 +79,11 @@ describe('kuery node types', function () {
|
|||
expect(wildcard.test(node, 'bazbar')).to.be(false);
|
||||
});
|
||||
|
||||
it('should return a true even when the string has newlines or tabs', function () {
|
||||
const node = wildcard.buildNode('foo*bar');
|
||||
expect(wildcard.test(node, 'foo\nbar')).to.be(true);
|
||||
expect(wildcard.test(node, 'foo\tbar')).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasLeadingWildcard', function () {
|
||||
|
|
|
@ -48,7 +48,7 @@ export function test(node, string) {
|
|||
.split(wildcardSymbol)
|
||||
.map(escapeRegExp)
|
||||
.join('.*');
|
||||
const regexp = new RegExp(`^${regex}$`);
|
||||
const regexp = new RegExp(`^${regex}$`, 's');
|
||||
return regexp.test(string);
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,8 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('a bad syntax query should show an error message', async function () {
|
||||
const expectedError = 'Discover: Expected "*", ":", "<", "<=", ">", ">=", "\\", [\\ \\t\\r\\n] or end of input but "(" found.';
|
||||
const expectedError = 'Discover: Expected "*", ":", "<", "<=", ">", ">=", "\\", "\\n", ' +
|
||||
'"\\r", "\\t", [\\ \\t\\r\\n] or end of input but "(" found.';
|
||||
await queryBar.setQuery('xxx(yyy))');
|
||||
await queryBar.submitQuery();
|
||||
const toastMessage = await PageObjects.header.getToastMessage();
|
||||
|
|
|
@ -49,4 +49,10 @@ describe('Kuery escape', function () {
|
|||
const expected = 'Hello, world, \\and \\<nice\\> to meet you!';
|
||||
expect(escapeKuery(value)).to.be(expected);
|
||||
});
|
||||
|
||||
it('should escape newlines and tabs', () => {
|
||||
const value = 'This\nhas\tnewlines\r\nwith\ttabs';
|
||||
const expected = 'This\\nhas\\tnewlines\\r\\nwith\\ttabs';
|
||||
expect(escapeKuery(value)).to.be(expected);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { flow } from 'lodash';
|
||||
|
||||
export function escapeQuotes(string) {
|
||||
return string.replace(/"/g, '\\"');
|
||||
}
|
||||
|
||||
export const escapeKuery = (string) => escapeNot(escapeAndOr(escapeSpecialCharacters(string)));
|
||||
export const escapeKuery = flow(escapeSpecialCharacters, escapeAndOr, escapeNot, escapeWhitespace);
|
||||
|
||||
// See the SpecialCharacter rule in kuery.peg
|
||||
function escapeSpecialCharacters(string) {
|
||||
|
@ -23,3 +25,11 @@ function escapeAndOr(string) {
|
|||
function escapeNot(string) {
|
||||
return string.replace(/not(\s+)/ig, '\\$&');
|
||||
}
|
||||
|
||||
// See the Space rule in kuery.peg
|
||||
function escapeWhitespace(string) {
|
||||
return string
|
||||
.replace(/\t/g, '\\t')
|
||||
.replace(/\r/g, '\\r')
|
||||
.replace(/\n/g, '\\n');
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue