Path: blob/dev/pkg/tmplexec/flow/builtin/dedupe.go
2073 views
package builtin12import (3"crypto/md5"4"reflect"56"github.com/Mzack9999/goja"7"github.com/projectdiscovery/nuclei/v3/pkg/types"8)910// Dedupe is a javascript builtin for deduping values11type Dedupe struct {12m map[string]goja.Value13VM *goja.Runtime14}1516// Add adds a value to the dedupe17func (d *Dedupe) Add(call goja.FunctionCall) goja.Value {18allVars := []any{}19for _, v := range call.Arguments {20if v.Export() == nil {21continue22}23if v.ExportType().Kind() == reflect.Slice {24// convert []datatype to []interface{}25// since it cannot be type asserted to []interface{} directly26rfValue := reflect.ValueOf(v.Export())27for i := 0; i < rfValue.Len(); i++ {28allVars = append(allVars, rfValue.Index(i).Interface())29}30} else {31allVars = append(allVars, v.Export())32}33}34for _, v := range allVars {35hash := hashValue(v)36if _, ok := d.m[hash]; ok {37continue38}39d.m[hash] = d.VM.ToValue(v)40}41return d.VM.ToValue(true)42}4344// Values returns all values from the dedupe45func (d *Dedupe) Values(call goja.FunctionCall) goja.Value {46tmp := []goja.Value{}47for _, v := range d.m {48tmp = append(tmp, v)49}50return d.VM.ToValue(tmp)51}5253// NewDedupe creates a new dedupe builtin object54func NewDedupe(vm *goja.Runtime) *Dedupe {55return &Dedupe{56m: make(map[string]goja.Value),57VM: vm,58}59}6061// hashValue returns a hash of the value62func hashValue(value interface{}) string {63res := types.ToString(value)64md5sum := md5.Sum([]byte(res))65return string(md5sum[:])66}676869