mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 11:55:40 +01:00
Extract more than one string from expr: category fields.
This commit is contained in:
parent
1d0499ddea
commit
8c8ccf6a2e
4 changed files with 64 additions and 6 deletions
|
|
@ -451,18 +451,19 @@ func (w *worker) extractCategories(label string, advisory any) error {
|
||||||
w.categories[label] = cats
|
w.categories[label] = cats
|
||||||
}
|
}
|
||||||
|
|
||||||
var result string
|
|
||||||
matcher := util.StringMatcher(&result)
|
|
||||||
|
|
||||||
const exprPrefix = "expr:"
|
const exprPrefix = "expr:"
|
||||||
|
|
||||||
for _, cat := range categories {
|
for _, cat := range categories {
|
||||||
if strings.HasPrefix(cat, exprPrefix) {
|
if strings.HasPrefix(cat, exprPrefix) {
|
||||||
expr := cat[len(exprPrefix):]
|
expr := cat[len(exprPrefix):]
|
||||||
|
var results []string
|
||||||
|
matcher := util.StringTreeMatcher(&results)
|
||||||
if err := w.expr.Extract(expr, matcher, true, advisory); err != nil {
|
if err := w.expr.Extract(expr, matcher, true, advisory); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cats[result] = true
|
for _, result := range results {
|
||||||
|
cats[result] = true
|
||||||
|
}
|
||||||
} else { // Normal
|
} else { // Normal
|
||||||
cats[cat] = true
|
cats[cat] = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,9 +195,10 @@ func (c *controller) upload(r *http.Request) (any, error) {
|
||||||
var dynamicCategories []string
|
var dynamicCategories []string
|
||||||
if catExprs := c.cfg.DynamicCategories(); len(catExprs) > 0 {
|
if catExprs := c.cfg.DynamicCategories(); len(catExprs) > 0 {
|
||||||
var err error
|
var err error
|
||||||
if dynamicCategories, err = pe.Strings(catExprs, true, content); err != nil {
|
if dynamicCategories, err = pe.StringsFromTree(
|
||||||
|
catExprs, true, content); err != nil {
|
||||||
// XXX: Should we die here?
|
// XXX: Should we die here?
|
||||||
log.Printf("eval of dynamic catecory expressions failed: %v\n", err)
|
log.Printf("eval of dynamic catergory expressions failed: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,12 @@ The following example file documents all available configuration options:
|
||||||
# If a list item starts with `expr:`
|
# If a list item starts with `expr:`
|
||||||
# the rest of the string is used as a JsonPath expression
|
# the rest of the string is used as a JsonPath expression
|
||||||
# to extract a string from the incoming advisories.
|
# to extract a string from the incoming advisories.
|
||||||
|
# If the result of the expression is a string this string
|
||||||
|
# is used. If the result is an array each element of
|
||||||
|
# this array is tested if it is a string or an array.
|
||||||
|
# If this test fails the expression fails. If the
|
||||||
|
# test succeeds the rules are applied recursively to
|
||||||
|
# collect all strings in the result.
|
||||||
# Strings not starting with `expr:` are taken verbatim.
|
# Strings not starting with `expr:` are taken verbatim.
|
||||||
# By default no category documents are created.
|
# By default no category documents are created.
|
||||||
# This example provides an overview over the syntax,
|
# This example provides an overview over the syntax,
|
||||||
|
|
|
||||||
50
util/json.go
50
util/json.go
|
|
@ -101,6 +101,37 @@ func StringMatcher(dst *string) func(any) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringTreeMatcher returns a matcher which add strings from
|
||||||
|
// stringss and recursively from arrays from strings.
|
||||||
|
func StringTreeMatcher(strings *[]string) func(any) error {
|
||||||
|
// Only add unique strings.
|
||||||
|
unique := func(s string) {
|
||||||
|
for _, t := range *strings {
|
||||||
|
if s == t {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*strings = append(*strings, s)
|
||||||
|
}
|
||||||
|
var recurse func(any) error
|
||||||
|
recurse = func(x any) error {
|
||||||
|
switch y := x.(type) {
|
||||||
|
case string:
|
||||||
|
unique(y)
|
||||||
|
case []any:
|
||||||
|
for _, z := range y {
|
||||||
|
if err := recurse(z); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported type: %T", x)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return recurse
|
||||||
|
}
|
||||||
|
|
||||||
// TimeMatcher stores a time with a given format.
|
// TimeMatcher stores a time with a given format.
|
||||||
func TimeMatcher(dst *time.Time, format string) func(any) error {
|
func TimeMatcher(dst *time.Time, format string) func(any) error {
|
||||||
return func(x any) error {
|
return func(x any) error {
|
||||||
|
|
@ -147,6 +178,25 @@ func (pe *PathEval) Match(matcher []PathEvalMatcher, doc any) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringsFromTree returns strings from the given exprs.
|
||||||
|
// 1. If a expression results a string this string is used.
|
||||||
|
// 2. if a 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
|
// Strings searches the given document for the given set of expressions
|
||||||
// and returns the corresponding strings. The optional flag indicates
|
// and returns the corresponding strings. The optional flag indicates
|
||||||
// if the expression evaluation have to succseed or not.
|
// if the expression evaluation have to succseed or not.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue