Skip to content

Commit

Permalink
Bugfix: Comparisons with time object were incorrect. (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
scudette authored Aug 12, 2024
1 parent 2a1740a commit 1f95429
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 3 deletions.
20 changes: 20 additions & 0 deletions fixtures/multi_vql_queries.golden
Original file line number Diff line number Diff line change
Expand Up @@ -1311,5 +1311,25 @@
"s.B": 2,
"B": 2
}
],
"086/000 Test timestamp comparisons: SELECT timestamp(epoch=1723428985) \u003c 1118628985, 1118628985 \u003c timestamp(epoch=1723428985), timestamp(epoch=1723428985) \u003c timestamp(epoch=1118628985), timestamp(epoch=1118628985) \u003c timestamp(epoch=1723428985), timestamp(epoch=1723428985) \u003e 1118628985, 1118628985 \u003e timestamp(epoch=1723428985), timestamp(epoch=1723428985) \u003e timestamp(epoch=1118628985), timestamp(epoch=1118628985) \u003e timestamp(epoch=1723428985), timestamp(epoch=1723428985) \u003c 1118628985.0, 1118628985.0 \u003c timestamp(epoch=1723428985), timestamp(epoch=1723428985) \u003e 1118628985.0, 1118628985.0 \u003e timestamp(epoch=1723428985), timestamp(epoch=1723428985) \u003c \"2024-08-12T02:15:25.176Z\", \"2024-08-12T02:15:25.176Z\" \u003c timestamp(epoch=1723428985), timestamp(epoch=1723428985) \u003e \"2024-08-12T02:15:25.176Z\", \"2024-08-12T02:15:25.176Z\" \u003e timestamp(epoch=1723428985) FROM scope()": [
{
"timestamp(epoch=1723428985) \u003c 1118628985": false,
"1118628985 \u003c timestamp(epoch=1723428985)": true,
"timestamp(epoch=1723428985) \u003c timestamp(epoch=1118628985)": false,
"timestamp(epoch=1118628985) \u003c timestamp(epoch=1723428985)": true,
"timestamp(epoch=1723428985) \u003e 1118628985": true,
"1118628985 \u003e timestamp(epoch=1723428985)": false,
"timestamp(epoch=1723428985) \u003e timestamp(epoch=1118628985)": true,
"timestamp(epoch=1118628985) \u003e timestamp(epoch=1723428985)": false,
"timestamp(epoch=1723428985) \u003c 1118628985.0": false,
"1118628985.0 \u003c timestamp(epoch=1723428985)": true,
"timestamp(epoch=1723428985) \u003e 1118628985.0": true,
"1118628985.0 \u003e timestamp(epoch=1723428985)": false,
"timestamp(epoch=1723428985) \u003c \"2024-08-12T02:15:25.176Z\"": false,
"\"2024-08-12T02:15:25.176Z\" \u003c timestamp(epoch=1723428985)": false,
"timestamp(epoch=1723428985) \u003e \"2024-08-12T02:15:25.176Z\"": false,
"\"2024-08-12T02:15:25.176Z\" \u003e timestamp(epoch=1723428985)": false
}
]
}
19 changes: 19 additions & 0 deletions protocols/protocol_gt.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,32 @@ func (self GtDispatcher) Gt(scope types.Scope, a types.Any, b types.Any) bool {
return false

case string:
if isTime(b) {
lhs, ok := utils.ToInt64(t)
if ok {
rhs, ok := toTime(b)
if ok {
return time.Unix(lhs, 0).After(*rhs)
}
}
}
rhs, ok := b.(string)
if ok {
return t > rhs
}

// If it is integer like, coerce to int.
case int, int8, int16, int32, int64, uint8, uint16, uint32, uint64:
if isTime(b) {
lhs, ok := utils.ToInt64(t)
if ok {
rhs, ok := toTime(b)
if ok {
return time.Unix(lhs, 0).After(*rhs)
}
}
}

lhs, ok := utils.ToInt64(t)
if ok {
return intGt(lhs, b)
Expand Down
46 changes: 43 additions & 3 deletions protocols/protocol_lt.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package protocols

import (
"math"
"time"

"www.velocidex.com/golang/vfilter/types"
Expand Down Expand Up @@ -64,13 +65,26 @@ func (self LtDispatcher) Lt(scope types.Scope, a types.Any, b types.Any) bool {
return false

case string:
rhs, ok := b.(string)
if ok {
return t < rhs
// Let string comparisons with time fall through to protocol
// selection.
if !isTime(b) {
rhs, ok := b.(string)
if ok {
return t < rhs
}
}

// If it is integer like, coerce to int.
case int, int8, int16, int32, int64, uint8, uint16, uint32, uint64:
if isTime(b) {
lhs, ok := utils.ToInt64(t)
if ok {
rhs, ok := toTime(b)
if ok {
return time.Unix(lhs, 0).Before(*rhs)
}
}
}
lhs, ok := utils.ToInt64(t)
if ok {
return intLt(lhs, b)
Expand Down Expand Up @@ -141,13 +155,39 @@ func (self LtDispatcher) Lt(scope types.Scope, a types.Any, b types.Any) bool {
return false
}

func isTime(a types.Any) bool {
switch a.(type) {
case time.Time:
return true
case *time.Time:
return true
}
return false
}

func toTime(a types.Any) (*time.Time, bool) {
switch t := a.(type) {
case time.Time:
return &t, true

case *time.Time:
return t, true

case float64:
sec_f, dec_f := math.Modf(t)
dec_f *= 1e9
res := time.Unix(int64(sec_f), int64(dec_f))
return &res, true

default:
// Maybe it is an int
sec, ok := utils.ToInt64(a)
if ok {
// Treat it as an epoch seconds
res := time.Unix(sec, 0)
return &res, true
}

return nil, false
}
}
Expand Down
22 changes: 22 additions & 0 deletions vfilter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,28 @@ LET Data <= (dict(A=1), dict(B=2))
LET s = scope()
SELECT s.A, A, s.B, B FROM Data
`},
// Comparing time to strings in unsupported in the base vfilter
// project, it is added with specialized handlers with
// Velociraptor.
{"Test timestamp comparisons", `
SELECT timestamp(epoch=1723428985) < 1118628985,
1118628985 < timestamp(epoch=1723428985),
timestamp(epoch=1723428985) < timestamp(epoch=1118628985),
timestamp(epoch=1118628985) < timestamp(epoch=1723428985),
timestamp(epoch=1723428985) > 1118628985,
1118628985 > timestamp(epoch=1723428985),
timestamp(epoch=1723428985) > timestamp(epoch=1118628985),
timestamp(epoch=1118628985) > timestamp(epoch=1723428985),
timestamp(epoch=1723428985) < 1118628985.0,
1118628985.0 < timestamp(epoch=1723428985),
timestamp(epoch=1723428985) > 1118628985.0,
1118628985.0 > timestamp(epoch=1723428985),
timestamp(epoch=1723428985) < "2024-08-12T02:15:25.176Z",
"2024-08-12T02:15:25.176Z" < timestamp(epoch=1723428985),
timestamp(epoch=1723428985) > "2024-08-12T02:15:25.176Z",
"2024-08-12T02:15:25.176Z" > timestamp(epoch=1723428985)
FROM scope()
`},
}

Expand Down

0 comments on commit 1f95429

Please sign in to comment.