Reducing data race via SyncLockMap (#3959)

* replacing custom map with synclockmap

* fixing initialization

* removing unused code
dev
Mzack9999 2023-07-24 16:50:28 +02:00 committed by GitHub
parent ae667a52d2
commit 5074722f17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 70 deletions

View File

@ -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{})
}

View File

@ -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,
} }