diff --git a/expr/expr_test.go b/expr/expr_test.go index 1375ddaf..48d559fb 100644 --- a/expr/expr_test.go +++ b/expr/expr_test.go @@ -1708,6 +1708,10 @@ func TestExtractMetric(t *testing.T) { "{something}", "{something}", }, + { + "a.b#c.d", + "a.b#c.d", + }, } for _, tt := range tests { diff --git a/expr/functions/groupByNode/function.go b/expr/functions/groupByNode/function.go index e1905b35..590ff0d3 100644 --- a/expr/functions/groupByNode/function.go +++ b/expr/functions/groupByNode/function.go @@ -65,13 +65,14 @@ func (f *groupByNode) Do(e parser.Expr, from, until int32, values map[parser.Met groups := make(map[string][]*types.MetricData) nodeList := []string{} - for _, a := range args { - metric := helper.ExtractMetric(a.Name) nodes := strings.Split(metric, ".") nodeKey := make([]string, 0, len(fields)) for _, f := range fields { + if f < 0 || f >= len(nodes) { + return nil, fmt.Errorf("%s: %w: %d", e.Target(), parser.ErrInvalidArgumentValue, f) + } nodeKey = append(nodeKey, nodes[f]) } node := strings.Join(nodeKey, ".") diff --git a/pkg/parser/interface.go b/pkg/parser/interface.go index 540410aa..5af6e4ad 100644 --- a/pkg/parser/interface.go +++ b/pkg/parser/interface.go @@ -47,6 +47,8 @@ var ( ErrUnknownTimeUnits = ParseError("unknown time units") // ErrDifferentCountMetrics is an eval error returned when a function that works on pairs of metrics receives arguments having different number of metrics. ErrDifferentCountMetrics = ParseError("both arguments must have the same number of metrics") + // ErrInvalidArgumentValue is an eval error returned when a function received an argument that has the right type but invalid value + ErrInvalidArgumentValue = ParseError("invalid function argument value") ) // ParseError is a type of errors returned from the parser diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 61d014c6..7a49be8f 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -426,7 +426,7 @@ func IsNameChar(r byte) bool { r == '[' || r == ']' || r == '^' || r == '$' || r == '<' || r == '>' || - r == '&' + r == '&' || r == '#' } func isDigit(r byte) bool {