iterative glob.go and limit FuzzMatch input size
This commit is contained in:
@@ -22,7 +22,7 @@ func validateGlobPattern(pattern string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// globMatch matches a string against a pattern with '*' wildcards, handling escaped '\*' literals.
|
||||
// globMatch matches a string against a pattern with * wildcards, handling escaped '\*' literals.
|
||||
func globMatch(pattern, str string) bool {
|
||||
if !validateGlobPattern(pattern) {
|
||||
return false
|
||||
@@ -31,55 +31,41 @@ func globMatch(pattern, str string) bool {
|
||||
// i is the index for the pattern
|
||||
// j is the index for the string
|
||||
var i, j int
|
||||
for i < len(pattern) && j < len(str) {
|
||||
switch pattern[i] {
|
||||
case '*':
|
||||
// skip consecutive '*' characters
|
||||
for i < len(pattern) && pattern[i] == '*' {
|
||||
i++
|
||||
}
|
||||
if i == len(pattern) {
|
||||
return true
|
||||
}
|
||||
|
||||
// match the rest of the pattern
|
||||
for j < len(str) {
|
||||
if globMatch(pattern[i:], str[j:]) {
|
||||
return true
|
||||
}
|
||||
j++
|
||||
}
|
||||
// starIdx keeps track of the position of the last * in the pattern.
|
||||
// matchIdx keeps track of the position in the string where the last * matched.
|
||||
var starIdx, matchIdx int = -1, -1
|
||||
|
||||
return false
|
||||
case '\\':
|
||||
// handle escaped '*'
|
||||
i++
|
||||
if i < len(pattern) && pattern[i] == '*' {
|
||||
if str[j] != '*' {
|
||||
return false
|
||||
}
|
||||
for j < len(str) {
|
||||
if i < len(pattern) && (pattern[i] == str[j] || pattern[i] == '\\' && i+1 < len(pattern) && pattern[i+1] == str[j]) {
|
||||
// characters match or if there's an escaped character that matches
|
||||
if pattern[i] == '\\' {
|
||||
// skip the escape character
|
||||
i++
|
||||
j++
|
||||
} else {
|
||||
if i >= len(pattern) || pattern[i] != str[j] {
|
||||
return false
|
||||
}
|
||||
i++
|
||||
j++
|
||||
}
|
||||
default:
|
||||
if pattern[i] != str[j] {
|
||||
return false
|
||||
}
|
||||
i++
|
||||
j++
|
||||
} else if i < len(pattern) && pattern[i] == '*' {
|
||||
// there's a * wildcard in the pattern
|
||||
starIdx = i
|
||||
matchIdx = j
|
||||
i++
|
||||
} else if starIdx != -1 {
|
||||
// there's a previous * wildcard, backtrack
|
||||
i = starIdx + 1
|
||||
matchIdx++
|
||||
j = matchIdx
|
||||
} else {
|
||||
// no match found
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// check for remaining characters in pattern
|
||||
// check for remaining characters in the pattern
|
||||
for i < len(pattern) && pattern[i] == '*' {
|
||||
i++
|
||||
}
|
||||
|
||||
return i == len(pattern) && j == len(str)
|
||||
// the entire pattern is processed, it's a match
|
||||
return i == len(pattern)
|
||||
}
|
||||
|
||||
@@ -491,6 +491,8 @@ func TestPolicyExamples(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
const maxFuzzInputLength = 128
|
||||
|
||||
func FuzzMatch(f *testing.F) {
|
||||
// Policy + Data examples
|
||||
f.Add([]byte(`[["==", ".status", "draft"]]`), []byte(`{"status": "draft"}`))
|
||||
@@ -520,6 +522,10 @@ func FuzzMatch(f *testing.F) {
|
||||
)
|
||||
|
||||
f.Fuzz(func(t *testing.T, policyBytes []byte, dataBytes []byte) {
|
||||
if len(policyBytes) > maxFuzzInputLength || len(dataBytes) > maxFuzzInputLength {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
policyNode, err := ipld.Decode(policyBytes, dagjson.Decode)
|
||||
if err != nil {
|
||||
t.Skip()
|
||||
|
||||
Reference in New Issue
Block a user