[kuery] support matching field names with newlines (#29539) (#30770)

* [kuery] support matching field names with newlines

* Add support for newlines in KQL grammar

* Add test for newlines in wildcards
This commit is contained in:
Spencer 2019-02-11 18:54:09 -08:00 committed by GitHub
parent 894adda928
commit de0952481a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 184 additions and 126 deletions

View file

@ -203,27 +203,33 @@ 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 = "\\n",
peg$c43 = { type: "literal", value: "\\n", description: "\"\\\\n\"" },
peg$c44 = function() { return '\n'; },
peg$c45 = "\\t",
peg$c46 = { type: "literal", value: "\\t", description: "\"\\\\t\"" },
peg$c47 = function() { return '\t'; },
peg$c48 = function(keyword) { return keyword; },
peg$c49 = /^[\\():<>"*]/,
peg$c50 = { type: "class", value: "[\\\\():<>\"*]", description: "[\\\\():<>\"*]" },
peg$c51 = "<=",
peg$c52 = { type: "literal", value: "<=", description: "\"<=\"" },
peg$c53 = function() { return 'lte'; },
peg$c54 = ">=",
peg$c55 = { type: "literal", value: ">=", description: "\">=\"" },
peg$c56 = function() { return 'gte'; },
peg$c57 = "<",
peg$c58 = { type: "literal", value: "<", description: "\"<\"" },
peg$c59 = function() { return 'lt'; },
peg$c60 = ">",
peg$c61 = { type: "literal", value: ">", description: "\">\"" },
peg$c62 = function() { return 'gt'; },
peg$c63 = /^[ \t\r\n]/,
peg$c64 = { type: "class", value: "[\\ \\t\\r\\n]", description: "[\\ \\t\\r\\n]" },
peg$c65 = function() { return parseCursor; },
peg$c66 = "@kuery-cursor@",
peg$c67 = { type: "literal", value: "@kuery-cursor@", description: "\"@kuery-cursor@\"" },
peg$c68 = function() { return cursorSymbol; },
peg$currPos = 0,
peg$savedPos = 0,
@ -1170,53 +1176,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 +1206,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 +1304,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 +1373,6 @@ module.exports = (function() {
peg$currPos = s0;
s0 = peg$FAILED;
}
} else {
peg$currPos = s0;
s0 = peg$FAILED;
}
}
}
@ -1436,6 +1448,41 @@ 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$c47();
}
s0 = s1;
}
return s0;
}
function peg$parseEscapedSpecialCharacter() {
var s0, s1, s2;
@ -1504,7 +1551,7 @@ module.exports = (function() {
}
if (s2 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c42(s2);
s1 = peg$c48(s2);
s0 = s1;
} else {
peg$currPos = s0;
@ -1535,12 +1582,12 @@ module.exports = (function() {
function peg$parseSpecialCharacter() {
var s0;
if (peg$c43.test(input.charAt(peg$currPos))) {
if (peg$c49.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$c50); }
}
return s0;
@ -1550,58 +1597,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$c51) {
s1 = peg$c51;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c46); }
if (peg$silentFails === 0) { peg$fail(peg$c52); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c47();
s1 = peg$c53();
}
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$c54) {
s1 = peg$c54;
peg$currPos += 2;
} else {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c49); }
if (peg$silentFails === 0) { peg$fail(peg$c55); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c50();
s1 = peg$c56();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 60) {
s1 = peg$c51;
s1 = peg$c57;
peg$currPos++;
} else {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c52); }
if (peg$silentFails === 0) { peg$fail(peg$c58); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c53();
s1 = peg$c59();
}
s0 = s1;
if (s0 === peg$FAILED) {
s0 = peg$currPos;
if (input.charCodeAt(peg$currPos) === 62) {
s1 = peg$c54;
s1 = peg$c60;
peg$currPos++;
} else {
s1 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c55); }
if (peg$silentFails === 0) { peg$fail(peg$c61); }
}
if (s1 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c56();
s1 = peg$c62();
}
s0 = s1;
}
@ -1614,12 +1661,12 @@ module.exports = (function() {
function peg$parseSpace() {
var s0;
if (peg$c57.test(input.charAt(peg$currPos))) {
if (peg$c63.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$c64); }
}
return s0;
@ -1630,23 +1677,23 @@ module.exports = (function() {
s0 = peg$currPos;
peg$savedPos = peg$currPos;
s1 = peg$c59();
s1 = peg$c65();
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$c66) {
s2 = peg$c66;
peg$currPos += 14;
} else {
s2 = peg$FAILED;
if (peg$silentFails === 0) { peg$fail(peg$c61); }
if (peg$silentFails === 0) { peg$fail(peg$c67); }
}
if (s2 !== peg$FAILED) {
peg$savedPos = s0;
s1 = peg$c62();
s1 = peg$c68();
s0 = s1;
} else {
peg$currPos = s0;

View file

@ -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,10 @@ OptionalSpace
}
/ Space*
EscapedWhitespace
= '\\n' { return '\n'; }
/ '\\t' { return '\t'; }
EscapedSpecialCharacter
= '\\' char:SpecialCharacter { return char; }

View file

@ -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 () {

View file

@ -48,7 +48,7 @@ export function test(node, string) {
.split(wildcardSymbol)
.map(escapeRegExp)
.join('.*');
const regexp = new RegExp(`^${regex}$`);
const regexp = new RegExp(`^${regex}$`, 'm');
return regexp.test(string);
}