mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-17 19:25:26 +00:00
* perf(*): replace `encoding/json` w/ sonic Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(utils): add `json` pkg (sonic wrapper) Signed-off-by: Dwi Siswanto <git@dw1.io> * chore(*): use `sonic` wrapper instead Signed-off-by: Dwi Siswanto <git@dw1.io> * chore(*): replace `sonic.ConfigStd` -> `json` (wrapper) Signed-off-by: Dwi Siswanto <git@dw1.io> * test(model): adjust expected marshal'd JSON Signed-off-by: Dwi Siswanto <git@dw1.io> * feat(json): dynamic backend; `sonic` -> `go-json` (fallback) Signed-off-by: Dwi Siswanto <git@dw1.io> * chore(json): merge config - as its not usable Signed-off-by: Dwi Siswanto <git@dw1.io> * chore(json): rm go version constraints Signed-off-by: Dwi Siswanto <git@dw1.io> * chore: go mod tidy Signed-off-by: Dwi Siswanto <git@dw1.io> --------- Signed-off-by: Dwi Siswanto <git@dw1.io>
121 lines
2.6 KiB
Go
121 lines
2.6 KiB
Go
package fuzz
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/invopop/jsonschema"
|
|
"github.com/projectdiscovery/nuclei/v3/pkg/utils/json"
|
|
mapsutil "github.com/projectdiscovery/utils/maps"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
var (
|
|
_ json.JSONCodec = &SliceOrMapSlice{}
|
|
_ yaml.Marshaler = &SliceOrMapSlice{}
|
|
_ yaml.Unmarshaler = &SliceOrMapSlice{}
|
|
)
|
|
|
|
type ValueOrKeyValue struct {
|
|
Key string
|
|
Value string
|
|
|
|
OriginalPayload string
|
|
}
|
|
|
|
func (v *ValueOrKeyValue) IsKV() bool {
|
|
return v.Key != ""
|
|
}
|
|
|
|
type SliceOrMapSlice struct {
|
|
Value []string
|
|
KV *mapsutil.OrderedMap[string, string]
|
|
}
|
|
|
|
func (v SliceOrMapSlice) JSONSchemaExtend(schema *jsonschema.Schema) *jsonschema.Schema {
|
|
schema = &jsonschema.Schema{
|
|
Title: schema.Title,
|
|
Description: schema.Description,
|
|
Type: "array",
|
|
Items: &jsonschema.Schema{
|
|
OneOf: []*jsonschema.Schema{
|
|
{
|
|
Type: "string",
|
|
},
|
|
{
|
|
Type: "object",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
return schema
|
|
}
|
|
|
|
func (v SliceOrMapSlice) JSONSchema() *jsonschema.Schema {
|
|
gotType := &jsonschema.Schema{
|
|
Title: "Payloads of Fuzz Rule",
|
|
Description: "Payloads to perform fuzzing substitutions with.",
|
|
Type: "array",
|
|
Items: &jsonschema.Schema{
|
|
OneOf: []*jsonschema.Schema{
|
|
{
|
|
Type: "string",
|
|
},
|
|
{
|
|
Type: "object",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
return gotType
|
|
}
|
|
|
|
// UnmarshalJSON implements json.Unmarshaler interface.
|
|
func (v *SliceOrMapSlice) UnmarshalJSON(data []byte) error {
|
|
// try to unmashal as a string and fallback to map
|
|
if err := json.Unmarshal(data, &v.Value); err == nil {
|
|
return nil
|
|
}
|
|
err := json.Unmarshal(data, &v.KV)
|
|
if err != nil {
|
|
return fmt.Errorf("object can be a key:value or a string")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// MarshalJSON implements json.Marshaler interface.
|
|
func (v SliceOrMapSlice) MarshalJSON() ([]byte, error) {
|
|
if v.KV != nil {
|
|
return json.Marshal(v.KV)
|
|
}
|
|
return json.Marshal(v.Value)
|
|
}
|
|
|
|
// UnmarshalYAML implements yaml.Unmarshaler interface.
|
|
func (v *SliceOrMapSlice) UnmarshalYAML(callback func(interface{}) error) error {
|
|
// try to unmarshal it as a string and fallback to map
|
|
if err := callback(&v.Value); err == nil {
|
|
return nil
|
|
}
|
|
|
|
// try with a mapslice
|
|
var node yaml.MapSlice
|
|
if err := callback(&node); err == nil {
|
|
tmpx := mapsutil.NewOrderedMap[string, string]()
|
|
// preserve order
|
|
for _, v := range node {
|
|
tmpx.Set(v.Key.(string), v.Value.(string))
|
|
}
|
|
v.KV = &tmpx
|
|
return nil
|
|
}
|
|
return fmt.Errorf("object can be a key:value or a string")
|
|
}
|
|
|
|
// MarshalYAML implements yaml.Marshaler interface.
|
|
func (v SliceOrMapSlice) MarshalYAML() (any, error) {
|
|
if v.KV != nil {
|
|
return v.KV, nil
|
|
}
|
|
return v.Value, nil
|
|
}
|