From 0745a0943d4050e864f00f9fc83a075d32d51d60 Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Thu, 26 Jan 2023 21:54:46 +0100 Subject: [PATCH] Separate compiling and evaluation of dynamic categories. --- cmd/csaf_aggregator/mirror.go | 22 +++++++++++++++------- cmd/csaf_provider/actions.go | 16 +++++++++++----- util/json.go | 33 ++++++++++++++------------------- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/cmd/csaf_aggregator/mirror.go b/cmd/csaf_aggregator/mirror.go index 3ea4837..fd37b3e 100644 --- a/cmd/csaf_aggregator/mirror.go +++ b/cmd/csaf_aggregator/mirror.go @@ -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 } diff --git a/cmd/csaf_provider/actions.go b/cmd/csaf_provider/actions.go index 67b36a5..0fa4e5b 100644 --- a/cmd/csaf_provider/actions.go +++ b/cmd/csaf_provider/actions.go @@ -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) } } diff --git a/util/json.go b/util/json.go index 985c7e1..be9f330 100644 --- a/util/json.go +++ b/util/json.go @@ -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.