Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add NoValidateJSONMarshaler option #527

Merged
merged 2 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion api.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ type Config struct {

// ValidateString indicates decoder and encoder to valid string values: decoder will return errors
// when unescaped control chars(\u0000-\u001f) in the string value of JSON.
ValidateString bool
ValidateString bool

// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
// after encoding the JSONMarshaler to JSON.
NoValidateJSONMarshaler bool
}

var (
Expand All @@ -87,6 +91,7 @@ var (
// ConfigFastest is the fastest config of APIs, aiming at speed.
ConfigFastest = Config{
NoQuoteTextMarshaler: true,
NoValidateJSONMarshaler: true,
}.Froze()
)

Expand Down
4 changes: 4 additions & 0 deletions encoder/encoder_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ const (
// before encoding it into JSON.
ValidateString Options = encoder.ValidateString

// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
// after encoding the JSONMarshaler to JSON.
NoValidateJSONMarshaler Options = encoder.NoValidateJSONMarshaler

// CompatibleWithStd is used to be compatible with std encoder.
CompatibleWithStd Options = encoder.CompatibleWithStd
)
Expand Down
14 changes: 14 additions & 0 deletions encoder/encoder_compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const (
bitNoQuoteTextMarshaler
bitNoNullSliceOrMap
bitValidateString
bitNoValidateJSONMarshaler

// used for recursive compile
bitPointerValue = 63
Expand Down Expand Up @@ -72,6 +73,10 @@ const (
// ValidateString indicates that encoder should validate the input string
// before encoding it into JSON.
ValidateString Options = 1 << bitValidateString

// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
// after encoding the JSONMarshaler to JSON.
NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler

// CompatibleWithStd is used to be compatible with std encoder.
CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler
Expand Down Expand Up @@ -116,6 +121,15 @@ func (self *Encoder) SetValidateString(f bool) {
}
}

// SetNoValidateJSONMarshaler specifies if option NoValidateJSONMarshaler opens
func (self *Encoder) SetNoValidateJSONMarshaler(f bool) {
if f {
self.Opts |= NoValidateJSONMarshaler
} else {
self.Opts &= ^NoValidateJSONMarshaler
}
}

// SetCompactMarshaler specifies if option CompactMarshaler opens
func (self *Encoder) SetCompactMarshaler(f bool) {
if f {
Expand Down
14 changes: 14 additions & 0 deletions internal/encoder/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const (
bitNoQuoteTextMarshaler
bitNoNullSliceOrMap
bitValidateString
bitNoValidateJSONMarshaler

// used for recursive compile
bitPointerValue = 63
Expand Down Expand Up @@ -71,6 +72,10 @@ const (
// ValidateString indicates that encoder should validate the input string
// before encoding it into JSON.
ValidateString Options = 1 << bitValidateString

// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
// after encoding the JSONMarshaler to JSON.
NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler

// CompatibleWithStd is used to be compatible with std encoder.
CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler
Expand Down Expand Up @@ -115,6 +120,15 @@ func (self *Encoder) SetValidateString(f bool) {
}
}

// SetNoValidateJSONMarshaler specifies if option NoValidateJSONMarshaler opens
func (self *Encoder) SetNoValidateJSONMarshaler(f bool) {
if f {
self.Opts |= NoValidateJSONMarshaler
} else {
self.Opts &= ^NoValidateJSONMarshaler
}
}

// SetCompactMarshaler specifies if option CompactMarshaler opens
func (self *Encoder) SetCompactMarshaler(f bool) {
if f {
Expand Down
6 changes: 4 additions & 2 deletions internal/encoder/primitives.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ func encodeJsonMarshaler(buf *[]byte, val json.Marshaler, opt Options) error {
if opt & CompactMarshaler != 0 {
return compact(buf, ret)
}
if ok, s := Valid(ret); !ok {
return error_marshaler(ret, s)
if opt & NoValidateJSONMarshaler == 0 {
if ok, s := Valid(ret); !ok {
return error_marshaler(ret, s)
}
}
*buf = append(*buf, ret...)
return nil
Expand Down
41 changes: 22 additions & 19 deletions sonic.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ func (cfg Config) Froze() API {
if cfg.ValidateString {
api.encoderOpts |= encoder.ValidateString
}
if cfg.NoValidateJSONMarshaler {
api.encoderOpts |= encoder.NoValidateJSONMarshaler
}

// configure decoder options:
if cfg.UseInt64 {
Expand Down Expand Up @@ -139,23 +142,23 @@ func (cfg frozenConfig) Valid(data []byte) bool {
// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
// a compile option to set the depth of recursive compile for the nested struct type.
func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
if err := encoder.Pretouch(vt, opts...); err != nil {
return err
}
if err := decoder.Pretouch(vt, opts...); err != nil {
return err
}
// to pretouch the corresponding pointer type as well
if vt.Kind() == reflect.Ptr {
vt = vt.Elem()
} else {
vt = reflect.PtrTo(vt)
}
if err := encoder.Pretouch(vt, opts...); err != nil {
return err
}
if err := decoder.Pretouch(vt, opts...); err != nil {
return err
}
return nil
if err := encoder.Pretouch(vt, opts...); err != nil {
return err
}
if err := decoder.Pretouch(vt, opts...); err != nil {
return err
}
// to pretouch the corresponding pointer type as well
if vt.Kind() == reflect.Ptr {
vt = vt.Elem()
} else {
vt = reflect.PtrTo(vt)
}
if err := encoder.Pretouch(vt, opts...); err != nil {
return err
}
if err := decoder.Pretouch(vt, opts...); err != nil {
return err
}
return nil
}