Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/fuzz/type.go
2070 views
1
package fuzz
2
3
import (
4
"fmt"
5
6
"github.com/invopop/jsonschema"
7
"github.com/projectdiscovery/nuclei/v3/pkg/utils/json"
8
mapsutil "github.com/projectdiscovery/utils/maps"
9
"gopkg.in/yaml.v2"
10
)
11
12
var (
13
_ json.JSONCodec = &SliceOrMapSlice{}
14
_ yaml.Marshaler = &SliceOrMapSlice{}
15
_ yaml.Unmarshaler = &SliceOrMapSlice{}
16
)
17
18
type ValueOrKeyValue struct {
19
Key string
20
Value string
21
22
OriginalPayload string
23
}
24
25
func (v *ValueOrKeyValue) IsKV() bool {
26
return v.Key != ""
27
}
28
29
type SliceOrMapSlice struct {
30
Value []string
31
KV *mapsutil.OrderedMap[string, string]
32
}
33
34
func (v SliceOrMapSlice) JSONSchemaExtend(schema *jsonschema.Schema) *jsonschema.Schema {
35
schema = &jsonschema.Schema{
36
Title: schema.Title,
37
Description: schema.Description,
38
Type: "array",
39
Items: &jsonschema.Schema{
40
OneOf: []*jsonschema.Schema{
41
{
42
Type: "string",
43
},
44
{
45
Type: "object",
46
},
47
},
48
},
49
}
50
return schema
51
}
52
53
func (v SliceOrMapSlice) JSONSchema() *jsonschema.Schema {
54
gotType := &jsonschema.Schema{
55
Title: "Payloads of Fuzz Rule",
56
Description: "Payloads to perform fuzzing substitutions with.",
57
Type: "array",
58
Items: &jsonschema.Schema{
59
OneOf: []*jsonschema.Schema{
60
{
61
Type: "string",
62
},
63
{
64
Type: "object",
65
},
66
},
67
},
68
}
69
return gotType
70
}
71
72
// UnmarshalJSON implements json.Unmarshaler interface.
73
func (v *SliceOrMapSlice) UnmarshalJSON(data []byte) error {
74
// try to unmashal as a string and fallback to map
75
if err := json.Unmarshal(data, &v.Value); err == nil {
76
return nil
77
}
78
err := json.Unmarshal(data, &v.KV)
79
if err != nil {
80
return fmt.Errorf("object can be a key:value or a string")
81
}
82
return nil
83
}
84
85
// MarshalJSON implements json.Marshaler interface.
86
func (v SliceOrMapSlice) MarshalJSON() ([]byte, error) {
87
if v.KV != nil {
88
return json.Marshal(v.KV)
89
}
90
return json.Marshal(v.Value)
91
}
92
93
// UnmarshalYAML implements yaml.Unmarshaler interface.
94
func (v *SliceOrMapSlice) UnmarshalYAML(callback func(interface{}) error) error {
95
// try to unmarshal it as a string and fallback to map
96
if err := callback(&v.Value); err == nil {
97
return nil
98
}
99
100
// try with a mapslice
101
var node yaml.MapSlice
102
if err := callback(&node); err == nil {
103
tmpx := mapsutil.NewOrderedMap[string, string]()
104
// preserve order
105
for _, v := range node {
106
tmpx.Set(v.Key.(string), v.Value.(string))
107
}
108
v.KV = &tmpx
109
return nil
110
}
111
return fmt.Errorf("object can be a key:value or a string")
112
}
113
114
// MarshalYAML implements yaml.Marshaler interface.
115
func (v SliceOrMapSlice) MarshalYAML() (any, error) {
116
if v.KV != nil {
117
return v.KV, nil
118
}
119
return v.Value, nil
120
}
121
122