Add case-insensitive flag to matchers and extractors

dev
Alexey Zhuchkov 2021-10-29 19:08:18 +03:00
parent e0afa2cee4
commit 3a47413cd4
6 changed files with 48 additions and 1 deletions

View File

@ -46,5 +46,15 @@ func (e *Extractor) CompileExtractors() error {
if e.Part == "" {
e.Part = "body"
}
if e.CaseInsensitive {
if e.Type != "kval" {
return fmt.Errorf("case-insensitive flag is supported only for 'kval' extractors (not '%s')", e.Type)
}
for i := range e.KVal {
e.KVal[i] = strings.ToLower(e.KVal[i])
}
}
return nil
}

View File

@ -34,8 +34,18 @@ func (e *Extractor) ExtractRegex(corpus string) map[string]struct{} {
// ExtractKval extracts key value pairs from a data map
func (e *Extractor) ExtractKval(data map[string]interface{}) map[string]struct{} {
results := make(map[string]struct{})
if e.CaseInsensitive {
inputData := data
data = make(map[string]interface{}, len(inputData))
for k, v := range inputData {
if s, ok := v.(string); ok {
v = strings.ToLower(s)
}
data[strings.ToLower(k)] = v
}
}
results := make(map[string]struct{})
for _, k := range e.KVal {
item, ok := data[k]
if !ok {

View File

@ -105,6 +105,13 @@ type Extractor struct {
// Internal, when set to true will allow using the value extracted
// in the next request for some protocols (like HTTP).
Internal bool `yaml:"internal,omitempty" jsonschema:"title=mark extracted value for internal variable use,description=Internal when set to true will allow using the value extracted in the next request for some protocols"`
// description: |
// CaseInsensitive enables case-insensitive extractions. Default is false.
// values:
// - false
// - true
CaseInsensitive bool `yaml:"case-insensitive,omitempty" jsonschema:"title=use case insensitive extract,description=use case insensitive extract"`
}
// ExtractorType is the type of the extractor specified

View File

@ -4,6 +4,7 @@ import (
"encoding/hex"
"fmt"
"regexp"
"strings"
"github.com/Knetic/govaluate"
@ -60,5 +61,14 @@ func (m *Matcher) CompileMatchers() error {
} else {
m.condition = ORCondition
}
if m.CaseInsensitive {
if m.Type != "word" {
return fmt.Errorf("case-insensitive flag is supported only for 'word' matchers (not '%s')", m.Type)
}
for i := range m.Words {
m.Words[i] = strings.ToLower(m.Words[i])
}
}
return nil
}

View File

@ -42,6 +42,10 @@ func (m *Matcher) MatchSize(length int) bool {
// MatchWords matches a word check against a corpus.
func (m *Matcher) MatchWords(corpus string, dynamicValues map[string]interface{}) (bool, []string) {
if m.CaseInsensitive {
corpus = strings.ToLower(corpus)
}
var matchedWords []string
// Iterate over all the words accepted as valid
for i, word := range m.Words {

View File

@ -105,6 +105,12 @@ type Matcher struct {
// values:
// - "hex"
Encoding string `yaml:"encoding,omitempty" jsonschema:"title=encoding for word field,description=Optional encoding for the word fields,enum=hex"`
// description: |
// CaseInsensitive enables case-insensitive matches. Default is false.
// values:
// - false
// - true
CaseInsensitive bool `yaml:"case-insensitive,omitempty" jsonschema:"title=use case insensitive match,description=use case insensitive match"`
// cached data for the compiled matcher
condition ConditionType