From f481b96ac0d992eb563ed48069199c0bf3685735 Mon Sep 17 00:00:00 2001 From: Lukasz Mierzwa Date: Thu, 31 Oct 2024 15:22:59 +0000 Subject: [PATCH] Fix a crash in vector() parsing --- docs/changelog.md | 6 ++ internal/parser/utils/source.go | 4 +- internal/parser/utils/source_test.go | 103 +++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 1be17bc6..cc835c55 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,11 @@ # Changelog +## v0.67.3 + +### Fixed + +- Fixed a crash when parsing `vector()` calls with non-number arguments. + ## v0.67.2 ### Fixed diff --git a/internal/parser/utils/source.go b/internal/parser/utils/source.go index c5153459..0c0c0a68 100644 --- a/internal/parser/utils/source.go +++ b/internal/parser/utils/source.go @@ -514,7 +514,9 @@ If you're hoping to get instance specific labels this way and alert when some ta s.GuaranteedLabels = nil s.FixedLabels = true s.AlwaysReturns = true - s.ReturnedNumbers = append(s.ReturnedNumbers, n.Args[0].(*promParser.NumberLiteral).Val) + if v, ok := n.Args[0].(*promParser.NumberLiteral); ok { + s.ReturnedNumbers = append(s.ReturnedNumbers, v.Val) + } s.ExcludeReason = setInMap( s.ExcludeReason, "", diff --git a/internal/parser/utils/source_test.go b/internal/parser/utils/source_test.go index 0a1b94c4..5564128a 100644 --- a/internal/parser/utils/source_test.go +++ b/internal/parser/utils/source_test.go @@ -2103,6 +2103,109 @@ sum(foo:count) by(job) > 20`, }, }, }, + { + expr: "vector(scalar(foo))", + output: []utils.Source{ + { + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "vector", + FixedLabels: true, + AlwaysReturns: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Calling `vector()` will return a vector value with no labels.", + Fragment: `vector(scalar(foo))`, + }, + }, + Call: &promParser.Call{ + Func: &promParser.Function{ + Name: "vector", + ArgTypes: []promParser.ValueType{ + promParser.ValueTypeScalar, + }, + Variadic: 0, + ReturnType: promParser.ValueTypeVector, + }, + Args: promParser.Expressions{ + &promParser.Call{ + Func: &promParser.Function{ + Name: "scalar", + ArgTypes: []promParser.ValueType{ + promParser.ValueTypeVector, + }, + Variadic: 0, + ReturnType: promParser.ValueTypeScalar, + }, + Args: promParser.Expressions{ + mustParseVector("foo", 14), + }, + PosRange: posrange.PositionRange{ + Start: 7, + End: 18, + }, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 19, + }, + }, + }, + }, + }, + { + expr: "vector(0.0 >= bool 0.5) == 1", + output: []utils.Source{ + { + Type: utils.FuncSource, + Returns: promParser.ValueTypeVector, + Operation: "vector", + FixedLabels: true, + AlwaysReturns: true, + ExcludeReason: map[string]utils.ExcludedLabel{ + "": { + Reason: "Calling `vector()` will return a vector value with no labels.", + Fragment: `vector(0.0 >= bool 0.5)`, + }, + }, + Call: &promParser.Call{ + Func: &promParser.Function{ + Name: "vector", + ArgTypes: []promParser.ValueType{ + promParser.ValueTypeScalar, + }, + Variadic: 0, + ReturnType: promParser.ValueTypeVector, + }, + Args: promParser.Expressions{ + &promParser.BinaryExpr{ + Op: promParser.GTE, + LHS: &promParser.NumberLiteral{ + Val: 0, + PosRange: posrange.PositionRange{ + Start: 7, + End: 10, + }, + }, + RHS: &promParser.NumberLiteral{ + Val: 0.5, + PosRange: posrange.PositionRange{ + Start: 20, + End: 23, + }, + }, + ReturnBool: true, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 24, + }, + }, + }, + }, + }, { expr: `sum_over_time(foo{job="myjob"}[5m])`, output: []utils.Source{