mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-18 08:35:26 +00:00
* refactor(fuzz): use `mapsutil.Map` type Signed-off-by: Dwi Siswanto <git@dw1.io> * fix(headless): handle empty `key` in `*Value.SetParsedValue` Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(fuzz): add type assertion checks Signed-off-by: Dwi Siswanto <git@dw1.io> --------- Signed-off-by: Dwi Siswanto <git@dw1.io>
127 lines
2.9 KiB
Go
127 lines
2.9 KiB
Go
package dataformat
|
|
|
|
import (
|
|
mapsutil "github.com/projectdiscovery/utils/maps"
|
|
"golang.org/x/exp/maps"
|
|
)
|
|
|
|
// KV is a key-value struct
|
|
// that is implemented or used by fuzzing package
|
|
// to represent a key-value pair
|
|
// sometimes order or key-value pair is important (query params)
|
|
// so we use ordered map to represent the data
|
|
// if it's not important/significant (ex: json,xml) we use map
|
|
// this also allows us to iteratively implement ordered map
|
|
type KV struct {
|
|
Map mapsutil.Map[string, any]
|
|
OrderedMap *mapsutil.OrderedMap[string, any]
|
|
}
|
|
|
|
// Clones the current state of the KV struct
|
|
func (kv *KV) Clone() KV {
|
|
newKV := KV{}
|
|
if kv.OrderedMap == nil {
|
|
newKV.Map = maps.Clone(kv.Map)
|
|
return newKV
|
|
}
|
|
clonedOrderedMap := kv.OrderedMap.Clone()
|
|
newKV.OrderedMap = &clonedOrderedMap
|
|
return newKV
|
|
}
|
|
|
|
// IsNIL returns true if the KV struct is nil
|
|
func (kv *KV) IsNIL() bool {
|
|
return kv.Map == nil && kv.OrderedMap == nil
|
|
}
|
|
|
|
// IsOrderedMap returns true if the KV struct is an ordered map
|
|
func (kv *KV) IsOrderedMap() bool {
|
|
return kv.OrderedMap != nil
|
|
}
|
|
|
|
// Set sets a value in the KV struct
|
|
func (kv *KV) Set(key string, value any) {
|
|
if kv.OrderedMap != nil {
|
|
kv.OrderedMap.Set(key, value)
|
|
return
|
|
}
|
|
if kv.Map == nil {
|
|
kv.Map = make(map[string]interface{})
|
|
}
|
|
kv.Map[key] = value
|
|
}
|
|
|
|
// Get gets a value from the KV struct
|
|
func (kv *KV) Get(key string) interface{} {
|
|
if kv.OrderedMap != nil {
|
|
value, ok := kv.OrderedMap.Get(key)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
return value
|
|
}
|
|
return kv.Map[key]
|
|
}
|
|
|
|
// Iterate iterates over the KV struct in insertion order
|
|
func (kv *KV) Iterate(f func(key string, value any) bool) {
|
|
if kv.OrderedMap != nil {
|
|
kv.OrderedMap.Iterate(func(key string, value any) bool {
|
|
return f(key, value)
|
|
})
|
|
return
|
|
}
|
|
for key, value := range kv.Map {
|
|
if !f(key, value) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// Delete deletes a key from the KV struct
|
|
func (kv *KV) Delete(key string) bool {
|
|
if kv.OrderedMap != nil {
|
|
_, ok := kv.OrderedMap.Get(key)
|
|
if !ok {
|
|
return false
|
|
}
|
|
kv.OrderedMap.Delete(key)
|
|
return true
|
|
}
|
|
_, ok := kv.Map[key]
|
|
if !ok {
|
|
return false
|
|
}
|
|
delete(kv.Map, key)
|
|
return true
|
|
}
|
|
|
|
// KVMap returns a new KV struct with the given map
|
|
func KVMap(data map[string]interface{}) KV {
|
|
return KV{Map: data}
|
|
}
|
|
|
|
// KVOrderedMap returns a new KV struct with the given ordered map
|
|
func KVOrderedMap(data *mapsutil.OrderedMap[string, any]) KV {
|
|
return KV{OrderedMap: data}
|
|
}
|
|
|
|
// ToMap converts the ordered map to a map
|
|
func ToMap(m *mapsutil.OrderedMap[string, any]) map[string]interface{} {
|
|
data := make(map[string]interface{})
|
|
m.Iterate(func(key string, value any) bool {
|
|
data[key] = value
|
|
return true
|
|
})
|
|
return data
|
|
}
|
|
|
|
// ToOrderedMap converts the map to an ordered map
|
|
func ToOrderedMap(data map[string]interface{}) *mapsutil.OrderedMap[string, any] {
|
|
m := mapsutil.NewOrderedMap[string, any]()
|
|
for key, value := range data {
|
|
m.Set(key, value)
|
|
}
|
|
return &m
|
|
}
|