forked from mirror/gin
feat(binding): add DisallowUnknownFields() in gin.Context.BindJSON() (#2028)
This commit is contained in:
parent
b80d675864
commit
f38c30a0d2
|
@ -64,6 +64,10 @@ type FooStructUseNumber struct {
|
||||||
Foo interface{} `json:"foo" binding:"required"`
|
Foo interface{} `json:"foo" binding:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FooStructDisallowUnknownFields struct {
|
||||||
|
Foo interface{} `json:"foo" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type FooBarStructForTimeType struct {
|
type FooBarStructForTimeType struct {
|
||||||
TimeFoo time.Time `form:"time_foo" time_format:"2006-01-02" time_utc:"1" time_location:"Asia/Chongqing"`
|
TimeFoo time.Time `form:"time_foo" time_format:"2006-01-02" time_utc:"1" time_location:"Asia/Chongqing"`
|
||||||
TimeBar time.Time `form:"time_bar" time_format:"2006-01-02" time_utc:"1"`
|
TimeBar time.Time `form:"time_bar" time_format:"2006-01-02" time_utc:"1"`
|
||||||
|
@ -194,6 +198,12 @@ func TestBindingJSONUseNumber2(t *testing.T) {
|
||||||
`{"foo": 123}`, `{"bar": "foo"}`)
|
`{"foo": 123}`, `{"bar": "foo"}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBindingJSONDisallowUnknownFields(t *testing.T) {
|
||||||
|
testBodyBindingDisallowUnknownFields(t, JSON,
|
||||||
|
"/", "/",
|
||||||
|
`{"foo": "bar"}`, `{"foo": "bar", "what": "this"}`)
|
||||||
|
}
|
||||||
|
|
||||||
func TestBindingForm(t *testing.T) {
|
func TestBindingForm(t *testing.T) {
|
||||||
testFormBinding(t, "POST",
|
testFormBinding(t, "POST",
|
||||||
"/", "/",
|
"/", "/",
|
||||||
|
@ -1162,6 +1172,25 @@ func testBodyBindingUseNumber2(t *testing.T, b Binding, name, path, badPath, bod
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testBodyBindingDisallowUnknownFields(t *testing.T, b Binding, path, badPath, body, badBody string) {
|
||||||
|
EnableDecoderDisallowUnknownFields = true
|
||||||
|
defer func() {
|
||||||
|
EnableDecoderDisallowUnknownFields = false
|
||||||
|
}()
|
||||||
|
|
||||||
|
obj := FooStructDisallowUnknownFields{}
|
||||||
|
req := requestWithBody("POST", path, body)
|
||||||
|
err := b.Bind(req, &obj)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "bar", obj.Foo)
|
||||||
|
|
||||||
|
obj = FooStructDisallowUnknownFields{}
|
||||||
|
req = requestWithBody("POST", badPath, badBody)
|
||||||
|
err = JSON.Bind(req, &obj)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "what")
|
||||||
|
}
|
||||||
|
|
||||||
func testBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
func testBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
||||||
assert.Equal(t, name, b.Name())
|
assert.Equal(t, name, b.Name())
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,12 @@ import (
|
||||||
// interface{} as a Number instead of as a float64.
|
// interface{} as a Number instead of as a float64.
|
||||||
var EnableDecoderUseNumber = false
|
var EnableDecoderUseNumber = false
|
||||||
|
|
||||||
|
// EnableDecoderDisallowUnknownFields is used to call the DisallowUnknownFields method
|
||||||
|
// on the JSON Decoder instance. DisallowUnknownFields causes the Decoder to
|
||||||
|
// return an error when the destination is a struct and the input contains object
|
||||||
|
// keys which do not match any non-ignored, exported fields in the destination.
|
||||||
|
var EnableDecoderDisallowUnknownFields = false
|
||||||
|
|
||||||
type jsonBinding struct{}
|
type jsonBinding struct{}
|
||||||
|
|
||||||
func (jsonBinding) Name() string {
|
func (jsonBinding) Name() string {
|
||||||
|
@ -40,6 +46,9 @@ func decodeJSON(r io.Reader, obj interface{}) error {
|
||||||
if EnableDecoderUseNumber {
|
if EnableDecoderUseNumber {
|
||||||
decoder.UseNumber()
|
decoder.UseNumber()
|
||||||
}
|
}
|
||||||
|
if EnableDecoderDisallowUnknownFields {
|
||||||
|
decoder.DisallowUnknownFields()
|
||||||
|
}
|
||||||
if err := decoder.Decode(obj); err != nil {
|
if err := decoder.Decode(obj); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
8
mode.go
8
mode.go
|
@ -71,12 +71,18 @@ func DisableBindValidation() {
|
||||||
binding.Validator = nil
|
binding.Validator = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableJsonDecoderUseNumber sets true for binding.EnableDecoderUseNumberto to
|
// EnableJsonDecoderUseNumber sets true for binding.EnableDecoderUseNumber to
|
||||||
// call the UseNumber method on the JSON Decoder instance.
|
// call the UseNumber method on the JSON Decoder instance.
|
||||||
func EnableJsonDecoderUseNumber() {
|
func EnableJsonDecoderUseNumber() {
|
||||||
binding.EnableDecoderUseNumber = true
|
binding.EnableDecoderUseNumber = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnableJsonDisallowUnknownFields sets true for binding.EnableDecoderDisallowUnknownFields to
|
||||||
|
// call the DisallowUnknownFields method on the JSON Decoder instance.
|
||||||
|
func EnableJsonDecoderDisallowUnknownFields() {
|
||||||
|
binding.EnableDecoderDisallowUnknownFields = true
|
||||||
|
}
|
||||||
|
|
||||||
// Mode returns currently gin mode.
|
// Mode returns currently gin mode.
|
||||||
func Mode() string {
|
func Mode() string {
|
||||||
return modeName
|
return modeName
|
||||||
|
|
|
@ -45,3 +45,9 @@ func TestEnableJsonDecoderUseNumber(t *testing.T) {
|
||||||
EnableJsonDecoderUseNumber()
|
EnableJsonDecoderUseNumber()
|
||||||
assert.True(t, binding.EnableDecoderUseNumber)
|
assert.True(t, binding.EnableDecoderUseNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEnableJsonDecoderDisallowUnknownFields(t *testing.T) {
|
||||||
|
assert.False(t, binding.EnableDecoderDisallowUnknownFields)
|
||||||
|
EnableJsonDecoderDisallowUnknownFields()
|
||||||
|
assert.True(t, binding.EnableDecoderDisallowUnknownFields)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue