|
@@ -11,6 +11,9 @@ import (
|
|
|
"github.com/modern-go/reflect2"
|
|
"github.com/modern-go/reflect2"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+// limit maximum depth of nesting, as allowed by https://tools.ietf.org/html/rfc7159#section-9
|
|
|
|
|
+const defaultMaxDepth = 10000
|
|
|
|
|
+
|
|
|
// Config customize how the API should behave.
|
|
// Config customize how the API should behave.
|
|
|
// The API is created from Config by Froze.
|
|
// The API is created from Config by Froze.
|
|
|
type Config struct {
|
|
type Config struct {
|
|
@@ -25,6 +28,7 @@ type Config struct {
|
|
|
ValidateJsonRawMessage bool
|
|
ValidateJsonRawMessage bool
|
|
|
ObjectFieldMustBeSimpleString bool
|
|
ObjectFieldMustBeSimpleString bool
|
|
|
CaseSensitive bool
|
|
CaseSensitive bool
|
|
|
|
|
+ MaxDepth int
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// API the public interface of this package.
|
|
// API the public interface of this package.
|
|
@@ -56,6 +60,7 @@ var ConfigCompatibleWithStandardLibrary = Config{
|
|
|
EscapeHTML: true,
|
|
EscapeHTML: true,
|
|
|
SortMapKeys: true,
|
|
SortMapKeys: true,
|
|
|
ValidateJsonRawMessage: true,
|
|
ValidateJsonRawMessage: true,
|
|
|
|
|
+ MaxDepth: -1, // encoding/json has no max depth (stack overflow at 2581101)
|
|
|
}.Froze()
|
|
}.Froze()
|
|
|
|
|
|
|
|
// ConfigFastest marshals float with only 6 digits precision
|
|
// ConfigFastest marshals float with only 6 digits precision
|
|
@@ -80,6 +85,7 @@ type frozenConfig struct {
|
|
|
streamPool *sync.Pool
|
|
streamPool *sync.Pool
|
|
|
iteratorPool *sync.Pool
|
|
iteratorPool *sync.Pool
|
|
|
caseSensitive bool
|
|
caseSensitive bool
|
|
|
|
|
+ maxDepth int
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (cfg *frozenConfig) initCache() {
|
|
func (cfg *frozenConfig) initCache() {
|
|
@@ -127,6 +133,9 @@ func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
|
|
|
|
|
|
|
|
// Froze forge API from config
|
|
// Froze forge API from config
|
|
|
func (cfg Config) Froze() API {
|
|
func (cfg Config) Froze() API {
|
|
|
|
|
+ if cfg.MaxDepth == 0 {
|
|
|
|
|
+ cfg.MaxDepth = defaultMaxDepth
|
|
|
|
|
+ }
|
|
|
api := &frozenConfig{
|
|
api := &frozenConfig{
|
|
|
sortMapKeys: cfg.SortMapKeys,
|
|
sortMapKeys: cfg.SortMapKeys,
|
|
|
indentionStep: cfg.IndentionStep,
|
|
indentionStep: cfg.IndentionStep,
|
|
@@ -134,6 +143,7 @@ func (cfg Config) Froze() API {
|
|
|
onlyTaggedField: cfg.OnlyTaggedField,
|
|
onlyTaggedField: cfg.OnlyTaggedField,
|
|
|
disallowUnknownFields: cfg.DisallowUnknownFields,
|
|
disallowUnknownFields: cfg.DisallowUnknownFields,
|
|
|
caseSensitive: cfg.CaseSensitive,
|
|
caseSensitive: cfg.CaseSensitive,
|
|
|
|
|
+ maxDepth: cfg.MaxDepth,
|
|
|
}
|
|
}
|
|
|
api.streamPool = &sync.Pool{
|
|
api.streamPool = &sync.Pool{
|
|
|
New: func() interface{} {
|
|
New: func() interface{} {
|