mirror of https://github.com/daffainfo/nuclei.git
Reducing data race via SyncLockMap (#3959)
* replacing custom map with synclockmap * fixing initialization * removing unused codedev
parent
ae667a52d2
commit
5074722f17
|
@ -1,31 +0,0 @@
|
||||||
package contextargs
|
|
||||||
|
|
||||||
// Args is a generic map with helpers
|
|
||||||
type Args map[string]interface{}
|
|
||||||
|
|
||||||
// Set a key with value
|
|
||||||
func (args Args) Set(key string, value interface{}) {
|
|
||||||
args[key] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the value associated to a key
|
|
||||||
func (args Args) Get(key string) (interface{}, bool) {
|
|
||||||
value, ok := args[key]
|
|
||||||
return value, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has verifies if the map contains the key
|
|
||||||
func (args Args) Has(key string) bool {
|
|
||||||
_, ok := args[key]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsEmpty verifies if the map is empty
|
|
||||||
func (Args Args) IsEmpty() bool {
|
|
||||||
return len(Args) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a new args map instance
|
|
||||||
func newArgs() map[string]interface{} {
|
|
||||||
return make(map[string]interface{})
|
|
||||||
}
|
|
|
@ -2,9 +2,8 @@ package contextargs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http/cookiejar"
|
"net/http/cookiejar"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"golang.org/x/exp/maps"
|
mapsutil "github.com/projectdiscovery/utils/maps"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Context implements a shared context struct to share information across multiple templates within a workflow
|
// Context implements a shared context struct to share information across multiple templates within a workflow
|
||||||
|
@ -15,10 +14,8 @@ type Context struct {
|
||||||
// CookieJar shared within workflow's http templates
|
// CookieJar shared within workflow's http templates
|
||||||
CookieJar *cookiejar.Jar
|
CookieJar *cookiejar.Jar
|
||||||
|
|
||||||
// Access to Args must use lock strategies to prevent data races
|
|
||||||
*sync.RWMutex
|
|
||||||
// Args is a workflow shared key-value store
|
// Args is a workflow shared key-value store
|
||||||
args Args
|
args *mapsutil.SyncLockMap[string, interface{}]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new contextargs instance
|
// Create a new contextargs instance
|
||||||
|
@ -32,15 +29,7 @@ func NewWithInput(input string) *Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) initialize() {
|
func (ctx *Context) initialize() {
|
||||||
ctx.args = newArgs()
|
ctx.args = &mapsutil.SyncLockMap[string, interface{}]{Map: mapsutil.Map[string, interface{}]{}}
|
||||||
ctx.RWMutex = &sync.RWMutex{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *Context) set(key string, value interface{}) {
|
|
||||||
ctx.Lock()
|
|
||||||
defer ctx.Unlock()
|
|
||||||
|
|
||||||
ctx.args.Set(key, value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the specific key-value pair
|
// Set the specific key-value pair
|
||||||
|
@ -49,7 +38,7 @@ func (ctx *Context) Set(key string, value interface{}) {
|
||||||
ctx.initialize()
|
ctx.initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.set(key, value)
|
_ = ctx.args.Set(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) isInitialized() bool {
|
func (ctx *Context) isInitialized() bool {
|
||||||
|
@ -60,49 +49,33 @@ func (ctx *Context) hasArgs() bool {
|
||||||
return ctx.isInitialized() && !ctx.args.IsEmpty()
|
return ctx.isInitialized() && !ctx.args.IsEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) get(key string) (interface{}, bool) {
|
|
||||||
ctx.RLock()
|
|
||||||
defer ctx.RUnlock()
|
|
||||||
|
|
||||||
return ctx.args.Get(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the value with specific key if exists
|
// Get the value with specific key if exists
|
||||||
func (ctx *Context) Get(key string) (interface{}, bool) {
|
func (ctx *Context) Get(key string) (interface{}, bool) {
|
||||||
if !ctx.hasArgs() {
|
if !ctx.hasArgs() {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.get(key)
|
return ctx.args.Get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) GetAll() Args {
|
func (ctx *Context) GetAll() *mapsutil.SyncLockMap[string, interface{}] {
|
||||||
if !ctx.hasArgs() {
|
if !ctx.hasArgs() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return maps.Clone(ctx.args)
|
return ctx.args.Clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) ForEach(f func(string, interface{})) {
|
func (ctx *Context) ForEach(f func(string, interface{})) {
|
||||||
ctx.RLock()
|
_ = ctx.args.Iterate(func(k string, v interface{}) error {
|
||||||
defer ctx.RUnlock()
|
|
||||||
|
|
||||||
for k, v := range ctx.args {
|
|
||||||
f(k, v)
|
f(k, v)
|
||||||
}
|
return nil
|
||||||
}
|
})
|
||||||
|
|
||||||
func (ctx *Context) has(key string) bool {
|
|
||||||
ctx.RLock()
|
|
||||||
defer ctx.RUnlock()
|
|
||||||
|
|
||||||
return ctx.args.Has(key)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has check if the key exists
|
// Has check if the key exists
|
||||||
func (ctx *Context) Has(key string) bool {
|
func (ctx *Context) Has(key string) bool {
|
||||||
return ctx.hasArgs() && ctx.has(key)
|
return ctx.hasArgs() && ctx.args.Has(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) HasArgs() bool {
|
func (ctx *Context) HasArgs() bool {
|
||||||
|
@ -112,7 +85,6 @@ func (ctx *Context) HasArgs() bool {
|
||||||
func (ctx *Context) Clone() *Context {
|
func (ctx *Context) Clone() *Context {
|
||||||
newCtx := &Context{
|
newCtx := &Context{
|
||||||
MetaInput: ctx.MetaInput.Clone(),
|
MetaInput: ctx.MetaInput.Clone(),
|
||||||
RWMutex: ctx.RWMutex,
|
|
||||||
args: ctx.args,
|
args: ctx.args,
|
||||||
CookieJar: ctx.CookieJar,
|
CookieJar: ctx.CookieJar,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue