1
0
Fork 0
mirror of https://github.com/gocsaf/csaf.git synced 2025-12-22 11:55:40 +01:00

Separate compiling and evaluation of dynamic categories.

This commit is contained in:
Sascha L. Teichmann 2023-01-26 21:54:46 +01:00
parent ff31ebfa0f
commit 0745a0943d
3 changed files with 40 additions and 31 deletions

View file

@ -453,22 +453,30 @@ func (w *worker) extractCategories(label string, advisory any) error {
const exprPrefix = "expr:"
var dynamic []string
matcher := util.StringTreeMatcher(&dynamic)
for _, cat := range categories {
if strings.HasPrefix(cat, exprPrefix) {
expr := cat[len(exprPrefix):]
var results []string
matcher := util.StringTreeMatcher(&results)
if err := w.expr.Extract(expr, matcher, true, advisory); err != nil {
return err
}
for _, result := range results {
cats[result] = true
// Compile first to check that the expression is okay.
if _, err := w.expr.Compile(expr); err != nil {
fmt.Printf("Compiling category expression %q failed: %v\n",
expr, err)
continue
}
// Ignore errors here as they result from not matching.
w.expr.Extract(expr, matcher, true, advisory)
} else { // Normal
cats[cat] = true
}
}
// Add dynamic categories.
for _, cat := range dynamic {
cats[cat] = true
}
return nil
}

View file

@ -194,11 +194,17 @@ func (c *controller) upload(r *http.Request) (any, error) {
// Check if we have to search for dynamic categories.
var dynamicCategories []string
if catExprs := c.cfg.DynamicCategories(); len(catExprs) > 0 {
var err error
if dynamicCategories, err = pe.StringsFromTree(
catExprs, true, content); err != nil {
// XXX: Should we die here?
log.Printf("eval of dynamic category expressions failed: %v\n", err)
matcher := util.StringTreeMatcher(&dynamicCategories)
for _, expr := range catExprs {
// Compile first to check that the expression is okay.
if _, err := pe.Compile(expr); err != nil {
log.Printf("Compiling category expression %q failed: %v\n",
expr, err)
continue
}
// Ignore errors here as they result from not matching.
pe.Extract(expr, matcher, true, content)
}
}

View file

@ -42,6 +42,20 @@ func NewPathEval() *PathEval {
}
}
// Compile compiles an expression and stores it in the
// internal cache on success.
func (pe *PathEval) Compile(expr string) (gval.Evaluable, error) {
if eval := pe.exprs[expr]; eval != nil {
return eval, nil
}
eval, err := pe.builder.NewEvaluable(expr)
if err != nil {
return nil, err
}
pe.exprs[expr] = eval
return eval, nil
}
// Eval evalutes expression expr on document doc.
// Returns the result of the expression.
func (pe *PathEval) Eval(expr string, doc any) (any, error) {
@ -178,25 +192,6 @@ func (pe *PathEval) Match(matcher []PathEvalMatcher, doc any) error {
return nil
}
// StringsFromTree returns strings from the given exprs.
// 1. If an expression results in a string this string is used.
// 2. if an expression results in an array the elements
// of this array are recursively treated with 1. and 2.
func (pe *PathEval) StringsFromTree(
exprs []string,
optional bool,
doc any,
) ([]string, error) {
results := make([]string, 0, len(exprs))
matcher := StringTreeMatcher(&results)
for _, expr := range exprs {
if err := pe.Extract(expr, matcher, optional, doc); err != nil {
return nil, err
}
}
return results, nil
}
// Strings searches the given document for the given set of expressions
// and returns the corresponding strings. The optional flag indicates
// if the expression evaluation have to succseed or not.