mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-15 00:13:30 +01:00
lib/storage: prevent from infinite loop if {__graphite__="..."}
filter matches a metric name with *
, [
or {
chars
The idea has been borrowed from https://github.com/VictoriaMetrics/VictoriaMetrics/pull/1137
This commit is contained in:
parent
e03233f441
commit
4443254fb9
@ -9,6 +9,8 @@
|
|||||||
* `process_resident_memory_peak_bytes` - peak RSS usage for the process.
|
* `process_resident_memory_peak_bytes` - peak RSS usage for the process.
|
||||||
* `process_virtual_memory_peak_bytes` - peak virtual memory usage for the process.
|
* `process_virtual_memory_peak_bytes` - peak virtual memory usage for the process.
|
||||||
|
|
||||||
|
* BUGFIX: prevent from infinite loop on `{__graphite__="..."}` filters when a metric name contains `*`, `{` or `[` chars.
|
||||||
|
|
||||||
|
|
||||||
# [v1.56.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.56.0)
|
# [v1.56.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.56.0)
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -15,6 +16,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/cgroup"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/cgroup"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fasttime"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fasttime"
|
||||||
@ -1122,14 +1124,16 @@ func (s *Storage) SearchTagValueSuffixes(accountID, projectID uint32, tr TimeRan
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SearchGraphitePaths returns all the matching paths for the given graphite query on the given tr.
|
// SearchGraphitePaths returns all the matching paths for the given graphite query on the given tr.
|
||||||
//
|
|
||||||
// If more than maxPaths paths is found, then only the first maxPaths paths is returned.
|
|
||||||
func (s *Storage) SearchGraphitePaths(accountID, projectID uint32, tr TimeRange, query []byte, maxPaths int, deadline uint64) ([]string, error) {
|
func (s *Storage) SearchGraphitePaths(accountID, projectID uint32, tr TimeRange, query []byte, maxPaths int, deadline uint64) ([]string, error) {
|
||||||
queryStr := string(query)
|
return s.searchGraphitePaths(accountID, projectID, tr, nil, query, maxPaths, deadline)
|
||||||
n := strings.IndexAny(queryStr, "*[{")
|
}
|
||||||
|
|
||||||
|
func (s *Storage) searchGraphitePaths(accountID, projectID uint32, tr TimeRange, qHead, qTail []byte, maxPaths int, deadline uint64) ([]string, error) {
|
||||||
|
n := strings.IndexAny(bytesutil.ToUnsafeString(qTail), "*[{")
|
||||||
if n < 0 {
|
if n < 0 {
|
||||||
// Verify that the query matches a metric name.
|
// Verify that qHead matches a metric name.
|
||||||
suffixes, err := s.SearchTagValueSuffixes(accountID, projectID, tr, nil, query, '.', 1, deadline)
|
qHead = append(qHead, qTail...)
|
||||||
|
suffixes, err := s.SearchTagValueSuffixes(accountID, projectID, tr, nil, qHead, '.', 1, deadline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1141,9 +1145,10 @@ func (s *Storage) SearchGraphitePaths(accountID, projectID uint32, tr TimeRange,
|
|||||||
// The query matches a metric name with additional suffix.
|
// The query matches a metric name with additional suffix.
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return []string{queryStr}, nil
|
return []string{string(qHead)}, nil
|
||||||
}
|
}
|
||||||
suffixes, err := s.SearchTagValueSuffixes(accountID, projectID, tr, nil, query[:n], '.', maxPaths, deadline)
|
qHead = append(qHead, qTail[:n]...)
|
||||||
|
suffixes, err := s.SearchTagValueSuffixes(accountID, projectID, tr, nil, qHead, '.', maxPaths, deadline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1153,34 +1158,34 @@ func (s *Storage) SearchGraphitePaths(accountID, projectID uint32, tr TimeRange,
|
|||||||
if len(suffixes) >= maxPaths {
|
if len(suffixes) >= maxPaths {
|
||||||
return nil, fmt.Errorf("more than maxPaths=%d suffixes found", maxPaths)
|
return nil, fmt.Errorf("more than maxPaths=%d suffixes found", maxPaths)
|
||||||
}
|
}
|
||||||
qPrefixStr := queryStr[:n]
|
qNode := qTail[n:]
|
||||||
qTail := ""
|
qTail = nil
|
||||||
qNode := queryStr[n:]
|
|
||||||
mustMatchLeafs := true
|
mustMatchLeafs := true
|
||||||
if m := strings.IndexByte(qNode, '.'); m >= 0 {
|
if m := bytes.IndexByte(qNode, '.'); m >= 0 {
|
||||||
qTail = qNode[m+1:]
|
qTail = qNode[m+1:]
|
||||||
qNode = qNode[:m+1]
|
qNode = qNode[:m+1]
|
||||||
mustMatchLeafs = false
|
mustMatchLeafs = false
|
||||||
}
|
}
|
||||||
re, err := getRegexpForGraphiteQuery(qNode)
|
re, err := getRegexpForGraphiteQuery(string(qNode))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
qHeadLen := len(qHead)
|
||||||
var paths []string
|
var paths []string
|
||||||
for _, suffix := range suffixes {
|
for _, suffix := range suffixes {
|
||||||
if len(paths) > maxPaths {
|
if len(paths) > maxPaths {
|
||||||
paths = paths[:maxPaths]
|
return nil, fmt.Errorf("more than maxPath=%d paths found", maxPaths)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
if !re.MatchString(suffix) {
|
if !re.MatchString(suffix) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if mustMatchLeafs {
|
if mustMatchLeafs {
|
||||||
paths = append(paths, qPrefixStr+suffix)
|
qHead = append(qHead[:qHeadLen], suffix...)
|
||||||
|
paths = append(paths, string(qHead))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
q := qPrefixStr + suffix + qTail
|
qHead = append(qHead[:qHeadLen], suffix...)
|
||||||
ps, err := s.SearchGraphitePaths(accountID, projectID, tr, []byte(q), maxPaths, deadline)
|
ps, err := s.searchGraphitePaths(accountID, projectID, tr, qHead, qTail, maxPaths, deadline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user