From b2e7938e25a6e8b12935a22203ab96a7be582dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linas=20Med=C5=BEi=C5=ABnas?= Date: Thu, 23 Oct 2025 09:42:19 +0200 Subject: [PATCH] [BUGFIX] PromQL: avoid panic parsing malformed info call (#17379) Signed-off-by: Linas Medziunas --- promql/parser/parse.go | 9 ++++++--- promql/parser/parse_test.go | 11 +++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/promql/parser/parse.go b/promql/parser/parse.go index 2a02fd4d53..d4bc4609eb 100644 --- a/promql/parser/parse.go +++ b/promql/parser/parse.go @@ -803,11 +803,14 @@ func (p *parser) checkAST(node Node) (typ ValueType) { p.addParseErrf(node.PositionRange(), "expected type %s in %s, got %s", DocumentedType(ValueTypeVector), fmt.Sprintf("call to function %q", n.Func.Name), DocumentedType(n.Args[1].Type())) } // Check the vector selector in the input doesn't contain a metric name - if n.Args[1].(*VectorSelector).Name != "" { + if vs, ok := n.Args[1].(*VectorSelector); ok && vs.Name != "" { p.addParseErrf(n.Args[1].PositionRange(), "expected label selectors only, got vector selector instead") + } else if ok { + // Set Vector Selector flag to bypass empty matcher check + vs.BypassEmptyMatcherCheck = true + } else { + p.addParseErrf(n.Args[1].PositionRange(), "expected label selectors only") } - // Set Vector Selector flag to bypass empty matcher check - n.Args[1].(*VectorSelector).BypassEmptyMatcherCheck = true } for i, arg := range n.Args { diff --git a/promql/parser/parse_test.go b/promql/parser/parse_test.go index 8d50d8c255..f3be0981a1 100644 --- a/promql/parser/parse_test.go +++ b/promql/parser/parse_test.go @@ -4375,6 +4375,17 @@ var testExpr = []struct { PosRange: posrange.PositionRange{Start: 0, End: 73}, }, }, + { + input: `info(http_request_counter_total{namespace="zzz"}, {foo="bar"} == 1)`, + fail: true, + errors: ParseErrors{ + ParseErr{ + PositionRange: posrange.PositionRange{Start: 50, End: 66}, + Err: errors.New("expected label selectors only"), + Query: `info(http_request_counter_total{namespace="zzz"}, {foo="bar"} == 1)`, + }, + }, + }, // Test that nested parentheses result in the correct position range. { input: `foo[11s+10s-5*2^2]`,