mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-18 03:15:25 +00:00
* Replaced strings.Replaced with fasttemplate reducing allocations Custom template parsing logic was replaced with fasttemplate package for reducing allocations in the replacer.Replace hotpath leading to allocation reduction which accounted for 30% of total nuclei allocations. $ go test -bench=. -benchmem goos: darwin goarch: arm64 pkg: github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/replacer BenchmarkReplacer-8 837232 1422 ns/op 2112 B/op 31 allocs/op BenchmarkReplacerNew-8 3672765 320.3 ns/op 48 B/op 4 allocs/op * Fixed tests failing * Use pre-compiled map of DSL expressions * Reworked expression parsing logic to reduce memory allocations $ go test -bench=. -benchmem goos: darwin goarch: arm64 pkg: github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/expressions BenchmarkEvaluate-8 31560 37769 ns/op 31731 B/op 265 allocs/op BenchmarkEvaluateNew-8 109144 9621 ns/op 6253 B/op 116 allocs/op
33 lines
1.3 KiB
Go
33 lines
1.3 KiB
Go
package replacer
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/valyala/fasttemplate"
|
|
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/marker"
|
|
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
|
)
|
|
|
|
// Replace replaces placeholders in template with values on the fly.
|
|
func Replace(template string, values map[string]interface{}) string {
|
|
valuesMap := make(map[string]interface{}, len(values))
|
|
for k, v := range values {
|
|
valuesMap[k] = types.ToString(v)
|
|
}
|
|
replaced := fasttemplate.ExecuteStringStd(template, marker.ParenthesisOpen, marker.ParenthesisClose, valuesMap)
|
|
final := fasttemplate.ExecuteStringStd(replaced, marker.General, marker.General, valuesMap)
|
|
return final
|
|
}
|
|
|
|
// Replace replaces one placeholder in template with one value on the fly.
|
|
func ReplaceOne(template string, key string, value interface{}) string {
|
|
data := replaceOneWithMarkers(template, key, value, marker.ParenthesisOpen, marker.ParenthesisClose)
|
|
return replaceOneWithMarkers(data, key, value, marker.General, marker.General)
|
|
}
|
|
|
|
// replaceOneWithMarkers is a helper function that perform one time replacement
|
|
func replaceOneWithMarkers(template, key string, value interface{}, openMarker, closeMarker string) string {
|
|
return strings.Replace(template, openMarker+key+closeMarker, types.ToString(value), 1)
|
|
}
|