mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
topdown/glob: Fix deferred mutex unlock issue. (#5274)
This commit wraps up the mutex-requiring code within the `glob.match` builtin in helper function, so that the deferred mutex unlock will always occur before the call at the end of the function to `iter()`. This helps prevent deadlocks during evaluation. Fixes #5273. Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
cases:
|
||||
- data: {}
|
||||
modules:
|
||||
- |
|
||||
package generated
|
||||
|
||||
p[x] {
|
||||
glob.match("*.github.com", ["."], "api.github.com", x)
|
||||
glob.match("*.github.com", ["."], "api.github.com", x)
|
||||
}
|
||||
# See: https://github.com/open-policy-agent/opa/issues/5273
|
||||
note: globmatch/no deadlocks for glob match
|
||||
query: data.generated.p = x
|
||||
sort_bindings: true
|
||||
want_result:
|
||||
- x:
|
||||
- true
|
||||
+14
-6
@@ -18,6 +18,7 @@ func builtinGlobMatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var delimiters []rune
|
||||
switch operands[1].Value.(type) {
|
||||
case ast.Null:
|
||||
@@ -33,8 +34,8 @@ func builtinGlobMatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
|
||||
default:
|
||||
return builtins.NewOperandTypeErr(2, operands[1].Value, "array", "null")
|
||||
}
|
||||
match, err := builtins.StringOperand(operands[2].Value, 3)
|
||||
|
||||
match, err := builtins.StringOperand(operands[2].Value, 3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -47,19 +48,26 @@ func builtinGlobMatch(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Ter
|
||||
}
|
||||
id := builder.String()
|
||||
|
||||
m, err := globCompileAndMatch(id, string(pattern), string(match), delimiters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return iter(ast.BooleanTerm(m))
|
||||
}
|
||||
|
||||
func globCompileAndMatch(id, pattern, match string, delimiters []rune) (bool, error) {
|
||||
globCacheLock.Lock()
|
||||
defer globCacheLock.Unlock()
|
||||
p, ok := globCache[id]
|
||||
if !ok {
|
||||
var err error
|
||||
if p, err = glob.Compile(string(pattern), delimiters...); err != nil {
|
||||
return err
|
||||
if p, err = glob.Compile(pattern, delimiters...); err != nil {
|
||||
return false, err
|
||||
}
|
||||
globCache[id] = p
|
||||
}
|
||||
|
||||
m := p.Match(string(match))
|
||||
return iter(ast.BooleanTerm(m))
|
||||
out := p.Match(match)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func builtinGlobQuoteMeta(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
|
||||
Reference in New Issue
Block a user