Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/operators/matchers/compile.go
2070 views
1
package matchers
2
3
import (
4
"encoding/hex"
5
"fmt"
6
"regexp"
7
"strings"
8
9
"github.com/Knetic/govaluate"
10
11
"github.com/projectdiscovery/nuclei/v3/pkg/operators/common/dsl"
12
)
13
14
// CompileMatchers performs the initial setup operation on a matcher
15
func (matcher *Matcher) CompileMatchers() error {
16
var ok bool
17
18
// Support hexadecimal encoding for matchers too.
19
if matcher.Encoding == "hex" {
20
for i, word := range matcher.Words {
21
if decoded, err := hex.DecodeString(word); err == nil && len(decoded) > 0 {
22
matcher.Words[i] = string(decoded)
23
}
24
}
25
}
26
27
// Set up the matcher type
28
computedType, err := toMatcherTypes(matcher.GetType().String())
29
if err != nil {
30
return fmt.Errorf("unknown matcher type specified: %s", matcher.Type)
31
}
32
33
matcher.matcherType = computedType
34
35
// Validate the matcher structure
36
if err := matcher.Validate(); err != nil {
37
return err
38
}
39
40
// By default, match on body if user hasn't provided any specific items
41
if matcher.Part == "" && matcher.GetType() != DSLMatcher {
42
matcher.Part = "body"
43
}
44
45
// Compile the regexes
46
for _, regex := range matcher.Regex {
47
compiled, err := regexp.Compile(regex)
48
if err != nil {
49
return fmt.Errorf("could not compile regex: %s", regex)
50
}
51
matcher.regexCompiled = append(matcher.regexCompiled, compiled)
52
}
53
54
// Compile and validate binary Values in matcher
55
for _, value := range matcher.Binary {
56
if decoded, err := hex.DecodeString(value); err != nil {
57
return fmt.Errorf("could not hex decode binary: %s", value)
58
} else {
59
matcher.binaryDecoded = append(matcher.binaryDecoded, string(decoded))
60
}
61
}
62
63
// Compile the dsl expressions
64
for _, dslExpression := range matcher.DSL {
65
compiledExpression, err := govaluate.NewEvaluableExpressionWithFunctions(dslExpression, dsl.HelperFunctions)
66
if err != nil {
67
return &dsl.CompilationError{DslSignature: dslExpression, WrappedError: err}
68
}
69
matcher.dslCompiled = append(matcher.dslCompiled, compiledExpression)
70
}
71
72
// Set up the condition type, if any.
73
if matcher.Condition != "" {
74
matcher.condition, ok = ConditionTypes[matcher.Condition]
75
if !ok {
76
return fmt.Errorf("unknown condition specified: %s", matcher.Condition)
77
}
78
} else {
79
matcher.condition = ORCondition
80
}
81
82
if matcher.CaseInsensitive {
83
if matcher.GetType() != WordsMatcher {
84
return fmt.Errorf("case-insensitive flag is supported only for 'word' matchers (not '%s')", matcher.Type)
85
}
86
for i := range matcher.Words {
87
matcher.Words[i] = strings.ToLower(matcher.Words[i])
88
}
89
}
90
return nil
91
}
92
93
// GetType returns the condition type of the matcher
94
// todo: the field should be exposed natively
95
func (matcher *Matcher) GetCondition() ConditionType {
96
return matcher.condition
97
}
98
99