Only read a KQL value as a date, number or boolean when it is the whole value

This commit is contained in:
André Duffeck committed 2026-10-30 08:54:05 +01:00
1 parent fef2b7e3fa
commit ff742249ba
4 files changed
+3454 -1568

No files matched your search

+35 -8
View File
@@ -47,7 +47,7 @@ PropertyRestrictionNodes <-
TextPropertyRestrictionNode
YesNoPropertyRestrictionNode <-
k:Key (OperatorColonNode / OperatorEqualNode) v:("true" / "false"){
k:Key (OperatorColonNode / OperatorEqualNode) v:("true" / "false") ValueEnd {
return buildBooleanNode(k, v, c.text, c.pos)
}
@@ -59,17 +59,13 @@ DateTimeRestrictionNode <-
OperatorLessNode /
OperatorEqualNode /
OperatorColonNode
) '"'? v:(
DateTime /
FullDate /
FullTime
) '"'? {
) v:DateTimeValue {
return buildDateTimeNode(k, o, v, c.text, c.pos)
} /
k:Key (
OperatorEqualNode /
OperatorColonNode
) '"'? v:NaturalLanguageDateTime '"'? {
) v:NaturalLanguageDateTimeValue {
return buildNaturalLanguageDateTimeNodes(k, v, c.text, c.pos)
}
@@ -79,7 +75,7 @@ NumberRestrictionNode <-
OperatorLessOrEqualNode /
OperatorGreaterNode /
OperatorLessNode
) '"'? v:Number '"'? {
) v:NumberValue {
return buildNumberNode(k, o, v, c.text, c.pos)
}
@@ -248,6 +244,37 @@ String <-
return unquote(c.text), nil
}
// a date or number only counts if it is the whole value, quoted or not.
// Otherwise the value is text: name:todays_report is not the date today
// followed by _report, and name:"2024-01-01""x""" is not a date followed by x"
DateTimeValue <-
'"' v:(DateTime / FullDate / FullTime) '"' !'"' {
return v, nil
} /
v:(DateTime / FullDate / FullTime) ValueEnd {
return v, nil
}
NaturalLanguageDateTimeValue <-
'"' v:NaturalLanguageDateTime '"' !'"' {
return v, nil
} /
v:NaturalLanguageDateTime ValueEnd {
return v, nil
}
NumberValue <-
'"' v:Number '"' !'"' {
return v, nil
} /
v:Number ValueEnd {
return v, nil
}
// where an unquoted date, number or boolean ends
ValueEnd <-
&[ \t()"] / EOF
Number <-
[0-9]+ ("." [0-9]+)? {
return string(c.text), nil
+3353 -1560
View File
File diff suppressed because it is too large. Load diff
+63
View File
@@ -1179,6 +1179,69 @@ func TestParse_Quoting(t *testing.T) {
},
},
},
// a date, number or boolean has to be the whole value, otherwise it's text
{
name: `name:"2024-01-01""foo"""`,
ast: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: `2024-01-01"foo"`},
},
},
},
{
name: `name:"today""s"""`,
ast: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: `today"s"`},
},
},
},
{
name: `name:2024-01-01foo`,
ast: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: "2024-01-01foo"},
},
},
},
{
name: `name:todays_report`,
ast: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: "todays_report"},
},
},
},
{
name: `name:trueish`,
ast: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Key: "name", Value: "trueish"},
},
},
},
{
name: `size>100abc`,
ast: &ast.Ast{
Nodes: []ast.Node{
&ast.StringNode{Value: "size>100abc"},
},
},
},
{
name: `Modified:"2023-09-05"foo`,
ast: &ast.Ast{
Nodes: []ast.Node{
&ast.DateTimeNode{
Key: "Modified",
Operator: &ast.OperatorNode{Value: ":"},
Value: mustParseTime(t, "2023-09-05"),
},
&ast.OperatorNode{Value: kql.BoolAND},
&ast.StringNode{Value: "foo"},
},
},
},
// a quote inside an unquoted value is an error, see TestBuild_ValidationErrors
}
+3
View File
@@ -73,6 +73,9 @@ func TestBuild_ValidationErrors(t *testing.T) {
`"""`,
`name:"cat""`,
`content:"foo\""`,
`Modified:"2023-09-05`,
`Modified:2023-09-05"`,
`size>"100`,
} {
got, err := kql.Builder{}.Build(q)
assert.Nil(got, q)