From 1079498182b6b9ff464536201b18f6329d1a93a9 Mon Sep 17 00:00:00 2001 From: gopherorg Date: Sat, 12 Jul 2025 05:20:47 +0800 Subject: [PATCH] refactor: use maps.Copy for cleaner map handling (#6283) Signed-off-by: gopherorg --- pkg/input/formats/openapi/examples.go | 5 ++--- pkg/js/gojs/gojs.go | 5 ++--- pkg/operators/operators.go | 5 ++--- pkg/projectfile/httputil.go | 5 ++--- pkg/protocols/common/generators/generators.go | 5 ++--- pkg/protocols/common/generators/maps.go | 5 ++--- pkg/protocols/dns/request.go | 9 +++------ pkg/protocols/file/request.go | 9 +++------ pkg/protocols/http/operators.go | 5 ++--- pkg/protocols/http/request.go | 9 +++------ pkg/protocols/javascript/js.go | 9 +++------ pkg/protocols/network/request.go | 17 +++++------------ pkg/protocols/offlinehttp/operators.go | 5 ++--- pkg/protocols/ssl/ssl.go | 9 +++------ pkg/protocols/websocket/websocket.go | 13 ++++--------- 15 files changed, 40 insertions(+), 75 deletions(-) diff --git a/pkg/input/formats/openapi/examples.go b/pkg/input/formats/openapi/examples.go index 2c79d5c89..6fb294cbf 100644 --- a/pkg/input/formats/openapi/examples.go +++ b/pkg/input/formats/openapi/examples.go @@ -2,6 +2,7 @@ package openapi import ( "fmt" + "maps" "slices" "github.com/getkin/kin-openapi/openapi3" @@ -162,9 +163,7 @@ func openAPIExample(schema *openapi3.Schema, cache map[*openapi3.Schema]*cachedS return nil, ErrNoExample } - for k, v := range value { - example[k] = v - } + maps.Copy(example, value) } return example, nil } diff --git a/pkg/js/gojs/gojs.go b/pkg/js/gojs/gojs.go index 5d4af6e87..e82dcb6f3 100644 --- a/pkg/js/gojs/gojs.go +++ b/pkg/js/gojs/gojs.go @@ -2,6 +2,7 @@ package gojs import ( "context" + "maps" "reflect" "sync" @@ -103,9 +104,7 @@ func wrapModuleFunc(runtime *goja.Runtime, fn interface{}) interface{} { } func (p *GojaModule) Set(objects Objects) Module { - for k, v := range objects { - p.sets[k] = v - } + maps.Copy(p.sets, objects) return p } diff --git a/pkg/operators/operators.go b/pkg/operators/operators.go index 1fb1ab1c5..ed2f0c4d2 100644 --- a/pkg/operators/operators.go +++ b/pkg/operators/operators.go @@ -2,6 +2,7 @@ package operators import ( "fmt" + "maps" "strconv" "strings" @@ -218,9 +219,7 @@ func (r *Result) Merge(result *Result) { r.DynamicValues[k] = sliceutil.Dedupe(append(r.DynamicValues[k], v...)) } } - for k, v := range result.PayloadValues { - r.PayloadValues[k] = v - } + maps.Copy(r.PayloadValues, result.PayloadValues) } // MatchFunc performs matching operation for a matcher on model and returns true or false. diff --git a/pkg/projectfile/httputil.go b/pkg/projectfile/httputil.go index dafeff3fd..078bd6841 100644 --- a/pkg/projectfile/httputil.go +++ b/pkg/projectfile/httputil.go @@ -6,6 +6,7 @@ import ( "encoding/gob" "encoding/hex" "io" + "maps" "net/http" ) @@ -85,9 +86,7 @@ func toInternalResponse(resp *http.Response, body []byte) *InternalResponse { intResp.HTTPMinor = resp.ProtoMinor intResp.StatusCode = resp.StatusCode intResp.StatusReason = resp.Status - for k, v := range resp.Header { - intResp.Headers[k] = v - } + maps.Copy(intResp.Headers, resp.Header) intResp.Body = body return intResp } diff --git a/pkg/protocols/common/generators/generators.go b/pkg/protocols/common/generators/generators.go index 5711b445f..fbb7f1554 100644 --- a/pkg/protocols/common/generators/generators.go +++ b/pkg/protocols/common/generators/generators.go @@ -4,6 +4,7 @@ package generators import ( "github.com/pkg/errors" + "maps" "github.com/projectdiscovery/nuclei/v3/pkg/catalog" "github.com/projectdiscovery/nuclei/v3/pkg/types" @@ -32,9 +33,7 @@ func New(payloads map[string]interface{}, attackType AttackType, templatePath st if err != nil { return nil, errors.Wrap(err, "could not parse payloads with aggression") } - for k, v := range values { - payloadsFinal[k] = v - } + maps.Copy(payloadsFinal, values) default: payloadsFinal[payloadName] = v } diff --git a/pkg/protocols/common/generators/maps.go b/pkg/protocols/common/generators/maps.go index 72bf705d8..ed2fc3a64 100644 --- a/pkg/protocols/common/generators/maps.go +++ b/pkg/protocols/common/generators/maps.go @@ -1,6 +1,7 @@ package generators import ( + maps0 "maps" "reflect" ) @@ -47,9 +48,7 @@ func MergeMapsMany(maps ...interface{}) map[string][]string { func MergeMaps(maps ...map[string]interface{}) map[string]interface{} { merged := make(map[string]interface{}) for _, m := range maps { - for k, v := range m { - merged[k] = v - } + maps0.Copy(merged, m) } return merged } diff --git a/pkg/protocols/dns/request.go b/pkg/protocols/dns/request.go index 6e82c047b..3cc0cd715 100644 --- a/pkg/protocols/dns/request.go +++ b/pkg/protocols/dns/request.go @@ -3,6 +3,7 @@ package dns import ( "encoding/hex" "fmt" + maps0 "maps" "strings" "sync" @@ -181,12 +182,8 @@ func (request *Request) execute(input *contextargs.Context, domain string, metad // expose response variables in proto_var format // this is no-op if the template is not a multi protocol template request.options.AddTemplateVars(input.MetaInput, request.Type(), request.ID, outputEvent) - for k, v := range previous { - outputEvent[k] = v - } - for k, v := range vars { - outputEvent[k] = v - } + maps0.Copy(outputEvent, previous) + maps0.Copy(outputEvent, vars) // add variables from template context before matching/extraction if request.options.HasTemplateCtx(input.MetaInput) { outputEvent = generators.MergeMaps(outputEvent, request.options.GetTemplateCtx(input.MetaInput).GetAll()) diff --git a/pkg/protocols/file/request.go b/pkg/protocols/file/request.go index 8296dee17..853cbb602 100644 --- a/pkg/protocols/file/request.go +++ b/pkg/protocols/file/request.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "fmt" "io" + "maps" "os" "path/filepath" "strings" @@ -276,9 +277,7 @@ func (request *Request) findMatchesWithReader(reader io.Reader, input *contextar gologger.Verbose().Msgf("[%s] Processing file %s chunk %s/%s", request.options.TemplateID, filePath, processedBytes, totalBytesString) dslMap := request.responseToDSLMap(lineContent, input.MetaInput.Input, filePath) - for k, v := range previous { - dslMap[k] = v - } + maps.Copy(dslMap, previous) // add vars to template context request.options.AddTemplateVars(input.MetaInput, request.Type(), request.ID, dslMap) // add template context variables to DSL map @@ -347,9 +346,7 @@ func (request *Request) buildEvent(input, filePath string, fileMatches []FileMat exprLines := make(map[string][]int) exprBytes := make(map[string][]int) internalEvent := request.responseToDSLMap("", input, filePath) - for k, v := range previous { - internalEvent[k] = v - } + maps.Copy(internalEvent, previous) for _, fileMatch := range fileMatches { exprLines[fileMatch.Expr] = append(exprLines[fileMatch.Expr], fileMatch.Line) exprBytes[fileMatch.Expr] = append(exprBytes[fileMatch.Expr], fileMatch.ByteIndex) diff --git a/pkg/protocols/http/operators.go b/pkg/protocols/http/operators.go index f9da8043b..298da25e1 100644 --- a/pkg/protocols/http/operators.go +++ b/pkg/protocols/http/operators.go @@ -1,6 +1,7 @@ package http import ( + "maps" "net/http" "strings" "time" @@ -108,9 +109,7 @@ func (request *Request) getMatchPart(part string, data output.InternalEvent) (st // responseToDSLMap converts an HTTP response to a map for use in DSL matching func (request *Request) responseToDSLMap(resp *http.Response, host, matched, rawReq, rawResp, body, headers string, duration time.Duration, extra map[string]interface{}) output.InternalEvent { data := make(output.InternalEvent, 12+len(extra)+len(resp.Header)+len(resp.Cookies())) - for k, v := range extra { - data[k] = v - } + maps.Copy(data, extra) for _, cookie := range resp.Cookies() { request.setHashOrDefault(data, strings.ToLower(cookie.Name), cookie.Value) } diff --git a/pkg/protocols/http/request.go b/pkg/protocols/http/request.go index fc181d1c5..d9b30ab72 100644 --- a/pkg/protocols/http/request.go +++ b/pkg/protocols/http/request.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "fmt" "io" + "maps" "net/http" "strconv" "strings" @@ -974,12 +975,8 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ if request.options.Interactsh != nil { request.options.Interactsh.MakePlaceholders(generatedRequest.interactshURLs, outputEvent) } - for k, v := range previousEvent { - finalEvent[k] = v - } - for k, v := range outputEvent { - finalEvent[k] = v - } + maps.Copy(finalEvent, previousEvent) + maps.Copy(finalEvent, outputEvent) // Add to history the current request number metadata if asked by the user. if request.NeedsRequestCondition() { diff --git a/pkg/protocols/javascript/js.go b/pkg/protocols/javascript/js.go index 0d4a41e03..fc5b30b98 100644 --- a/pkg/protocols/javascript/js.go +++ b/pkg/protocols/javascript/js.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "maps" "net" "strings" "sync/atomic" @@ -304,9 +305,7 @@ func (request *Request) ExecuteWithResults(target *contextargs.Context, dynamicV templateCtx := request.options.GetTemplateCtx(input.MetaInput) payloadValues := generators.BuildPayloadFromOptions(request.options.Options) - for k, v := range dynamicValues { - payloadValues[k] = v - } + maps.Copy(payloadValues, dynamicValues) payloadValues["Hostname"] = hostPort payloadValues["Host"] = hostname @@ -620,9 +619,7 @@ func (request *Request) generateEventData(input *contextargs.Context, values map } data := make(map[string]interface{}) - for k, v := range values { - data[k] = v - } + maps.Copy(data, values) data["type"] = request.Type().String() data["request-pre-condition"] = beautifyJavascript(request.PreCondition) data["request"] = beautifyJavascript(request.Code) diff --git a/pkg/protocols/network/request.go b/pkg/protocols/network/request.go index 189724033..24071763e 100644 --- a/pkg/protocols/network/request.go +++ b/pkg/protocols/network/request.go @@ -3,6 +3,7 @@ package network import ( "encoding/hex" "fmt" + maps0 "maps" "net" "net/url" "os" @@ -375,9 +376,7 @@ func (request *Request) executeRequestWithPayloads(variables map[string]interfac // Run any internal extractors for the request here and add found values to map. if request.CompiledOperators != nil { values := request.CompiledOperators.ExecuteInternalExtractors(map[string]interface{}{input.Name: bufferStr}, request.Extract) - for k, v := range values { - payloads[k] = v - } + maps0.Copy(payloads, values) } } } @@ -427,15 +426,9 @@ func (request *Request) executeRequestWithPayloads(variables map[string]interfac if request.options.StopAtFirstMatch { outputEvent["stop-at-first-match"] = true } - for k, v := range previous { - outputEvent[k] = v - } - for k, v := range interimValues { - outputEvent[k] = v - } - for k, v := range inputEvents { - outputEvent[k] = v - } + maps0.Copy(outputEvent, previous) + maps0.Copy(outputEvent, interimValues) + maps0.Copy(outputEvent, inputEvents) if request.options.Interactsh != nil { request.options.Interactsh.MakePlaceholders(interactshURLs, outputEvent) } diff --git a/pkg/protocols/offlinehttp/operators.go b/pkg/protocols/offlinehttp/operators.go index be1a8b860..cbce83cb6 100644 --- a/pkg/protocols/offlinehttp/operators.go +++ b/pkg/protocols/offlinehttp/operators.go @@ -1,6 +1,7 @@ package offlinehttp import ( + "maps" "net/http" "strings" "time" @@ -103,9 +104,7 @@ func getMatchPart(part string, data output.InternalEvent) (string, bool) { // responseToDSLMap converts an HTTP response to a map for use in DSL matching func (request *Request) responseToDSLMap(resp *http.Response, host, matched, rawReq, rawResp, body, headers string, duration time.Duration, extra map[string]interface{}) output.InternalEvent { data := make(output.InternalEvent, 12+len(extra)+len(resp.Header)+len(resp.Cookies())) - for k, v := range extra { - data[k] = v - } + maps.Copy(data, extra) for _, cookie := range resp.Cookies() { data[strings.ToLower(cookie.Name)] = cookie.Value } diff --git a/pkg/protocols/ssl/ssl.go b/pkg/protocols/ssl/ssl.go index 8764d6f5f..72d666422 100644 --- a/pkg/protocols/ssl/ssl.go +++ b/pkg/protocols/ssl/ssl.go @@ -2,6 +2,7 @@ package ssl import ( "fmt" + "maps" "net" "strings" "time" @@ -206,9 +207,7 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, dynamicVa requestOptions := request.options payloadValues := generators.BuildPayloadFromOptions(request.options.Options) - for k, v := range dynamicValues { - payloadValues[k] = v - } + maps.Copy(payloadValues, dynamicValues) payloadValues["Hostname"] = hostPort payloadValues["Host"] = hostname @@ -271,9 +270,7 @@ func (request *Request) ExecuteWithResults(input *contextargs.Context, dynamicVa jsonDataString := string(jsonData) data := make(map[string]interface{}) - for k, v := range payloadValues { - data[k] = v - } + maps.Copy(data, payloadValues) data["type"] = request.Type().String() data["response"] = jsonDataString data["host"] = input.MetaInput.Input diff --git a/pkg/protocols/websocket/websocket.go b/pkg/protocols/websocket/websocket.go index 175002e53..84062373d 100644 --- a/pkg/protocols/websocket/websocket.go +++ b/pkg/protocols/websocket/websocket.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "fmt" "io" + "maps" "net" "net/http" "net/url" @@ -274,12 +275,8 @@ func (request *Request) executeRequestWithPayloads(target *contextargs.Context, request.options.AddTemplateVars(target.MetaInput, request.Type(), request.ID, data) data = generators.MergeMaps(data, request.options.GetTemplateCtx(target.MetaInput).GetAll()) - for k, v := range previous { - data[k] = v - } - for k, v := range events { - data[k] = v - } + maps.Copy(data, previous) + maps.Copy(data, events) event := eventcreator.CreateEventWithAdditionalOptions(request, data, requestOptions.Options.Debug || requestOptions.Options.DebugResponse, func(internalWrappedEvent *output.InternalWrappedEvent) { internalWrappedEvent.OperatorsResult.PayloadValues = payloadValues @@ -337,9 +334,7 @@ func (request *Request) readWriteInputWebsocket(conn net.Conn, payloadValues map // Run any internal extractors for the request here and add found values to map. if request.CompiledOperators != nil { values := request.CompiledOperators.ExecuteInternalExtractors(map[string]interface{}{req.Name: bufferStr}, protocols.MakeDefaultExtractFunc) - for k, v := range values { - inputEvents[k] = v - } + maps.Copy(inputEvents, values) } } }