mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
guards against too many matches.
Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com>
This commit is contained in:
parent
639cd00721
commit
d217825af8
|
@ -19,6 +19,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const maxSetMatches = 256
|
||||||
|
|
||||||
type FastRegexMatcher struct {
|
type FastRegexMatcher struct {
|
||||||
re *regexp.Regexp
|
re *regexp.Regexp
|
||||||
|
|
||||||
|
@ -86,12 +88,12 @@ func findSetMatches(re *syntax.Regexp, base string) []string {
|
||||||
var matches []string
|
var matches []string
|
||||||
var totalSet int
|
var totalSet int
|
||||||
for i := 0; i < len(re.Rune); i = i + 2 {
|
for i := 0; i < len(re.Rune); i = i + 2 {
|
||||||
totalSet += int(re.Rune[i+1] - re.Rune[i])
|
totalSet += int(re.Rune[i+1]-re.Rune[i]) + 1
|
||||||
}
|
}
|
||||||
// limits the total characters that can be used to create matches.
|
// limits the total characters that can be used to create matches.
|
||||||
// In some case like negation [^0-9] a lot of possibilities exists and that
|
// In some case like negation [^0-9] a lot of possibilities exists and that
|
||||||
// can create thousands of possible matches at which points we're better off using regexp.
|
// can create thousands of possible matches at which points we're better off using regexp.
|
||||||
if totalSet > 100 {
|
if totalSet > maxSetMatches {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for i := 0; i < len(re.Rune); i = i + 2 {
|
for i := 0; i < len(re.Rune); i = i + 2 {
|
||||||
|
@ -128,6 +130,9 @@ func findSetMatchesFromConcat(re *syntax.Regexp, base string) []string {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if tooManyMatches(newMatches, m...) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
newMatches = append(newMatches, m...)
|
newMatches = append(newMatches, m...)
|
||||||
}
|
}
|
||||||
matches = newMatches
|
matches = newMatches
|
||||||
|
@ -143,6 +148,9 @@ func findSetMatchesFromAlternate(re *syntax.Regexp, base string) []string {
|
||||||
if found == nil {
|
if found == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if tooManyMatches(setMatches, found...) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
setMatches = append(setMatches, found...)
|
setMatches = append(setMatches, found...)
|
||||||
}
|
}
|
||||||
return setMatches
|
return setMatches
|
||||||
|
@ -163,6 +171,11 @@ func isCaseInsensitive(reg *syntax.Regexp) bool {
|
||||||
return (reg.Flags & syntax.FoldCase) != 0
|
return (reg.Flags & syntax.FoldCase) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tooManyMatches guards against creating too many set matches
|
||||||
|
func tooManyMatches(matches []string, new ...string) bool {
|
||||||
|
return len(matches)+len(new) > maxSetMatches
|
||||||
|
}
|
||||||
|
|
||||||
func (m *FastRegexMatcher) MatchString(s string) bool {
|
func (m *FastRegexMatcher) MatchString(s string) bool {
|
||||||
if len(m.setMatches) != 0 {
|
if len(m.setMatches) != 0 {
|
||||||
for _, match := range m.setMatches {
|
for _, match := range m.setMatches {
|
||||||
|
|
|
@ -137,6 +137,8 @@ func TestFindSetMatches(t *testing.T) {
|
||||||
{"(api|rpc)_(v1|prom)_((?i)push|query)", nil},
|
{"(api|rpc)_(v1|prom)_((?i)push|query)", nil},
|
||||||
// too high charset combination
|
// too high charset combination
|
||||||
{"(api|rpc)_[^0-9]", nil},
|
{"(api|rpc)_[^0-9]", nil},
|
||||||
|
// too many combinations
|
||||||
|
{"[a-z][a-z]", nil},
|
||||||
} {
|
} {
|
||||||
c := c
|
c := c
|
||||||
t.Run(c.pattern, func(t *testing.T) {
|
t.Run(c.pattern, func(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue