Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/utils/yaml/preprocess.go
2070 views
1
package yaml
2
3
import (
4
"bytes"
5
"errors"
6
"os"
7
"regexp"
8
"strings"
9
10
"github.com/projectdiscovery/nuclei/v3/pkg/templates/extensions"
11
fileutil "github.com/projectdiscovery/utils/file"
12
stringsutil "github.com/projectdiscovery/utils/strings"
13
)
14
15
var reImportsPattern = regexp.MustCompile(`(?m)# !include:(.+.yaml)`)
16
17
// StrictSyntax determines if pre-processing directives should be observed
18
var StrictSyntax bool
19
20
// PreProcess all include directives
21
func PreProcess(data []byte) ([]byte, error) {
22
// find all matches like !include:path\n
23
importMatches := reImportsPattern.FindAllSubmatch(data, -1)
24
hasImportDirectives := len(importMatches) > 0
25
26
if hasImportDirectives && StrictSyntax {
27
return data, errors.New("include directive preprocessing is disabled")
28
}
29
30
var replaceItems []string
31
32
for _, match := range importMatches {
33
var (
34
matchString string
35
includeFileName string
36
)
37
matchBytes := match[0]
38
matchString = string(matchBytes)
39
if len(match) > 0 {
40
includeFileName = string(match[1])
41
}
42
43
// gets the number of tabs/spaces between the last \n and the beginning of the match
44
matchIndex := bytes.Index(data, matchBytes)
45
lastNewLineIndex := bytes.LastIndex(data[:matchIndex], []byte("\n"))
46
padBytes := data[lastNewLineIndex:matchIndex]
47
48
// check if the file exists
49
if fileutil.FileExists(includeFileName) {
50
// and in case replace the comment with it
51
includeFileContent, err := os.ReadFile(includeFileName)
52
if err != nil {
53
return nil, err
54
}
55
// if it's yaml, tries to preprocess that too recursively
56
if stringsutil.HasSuffixAny(includeFileName, extensions.YAML) {
57
if subIncludedFileContent, err := PreProcess(includeFileContent); err == nil {
58
includeFileContent = subIncludedFileContent
59
} else {
60
return nil, err
61
}
62
}
63
64
// pad each line of file content with padBytes
65
includeFileContent = bytes.ReplaceAll(includeFileContent, []byte("\n"), padBytes)
66
67
replaceItems = append(replaceItems, matchString)
68
replaceItems = append(replaceItems, string(includeFileContent))
69
}
70
}
71
72
replacer := strings.NewReplacer(replaceItems...)
73
74
return []byte(replacer.Replace(string(data))), nil
75
}
76
77