Skip to content

Commit

Permalink
feat(binding): add DisallowUnknownFields() in gin.Context.BindJSON() (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
kszafran authored and thinkerou committed Sep 6, 2019
1 parent b80d675 commit f38c30a
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 1 deletion.
29 changes: 29 additions & 0 deletions binding/binding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ type FooStructUseNumber struct {
Foo interface{} `json:"foo" binding:"required"`
}

type FooStructDisallowUnknownFields struct {
Foo interface{} `json:"foo" binding:"required"`
}

type FooBarStructForTimeType struct {
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"`
Expand Down Expand Up @@ -194,6 +198,12 @@ func TestBindingJSONUseNumber2(t *testing.T) {
`{"foo": 123}`, `{"bar": "foo"}`)
}

func TestBindingJSONDisallowUnknownFields(t *testing.T) {
testBodyBindingDisallowUnknownFields(t, JSON,
"/", "/",
`{"foo": "bar"}`, `{"foo": "bar", "what": "this"}`)
}

func TestBindingForm(t *testing.T) {
testFormBinding(t, "POST",
"/", "/",
Expand Down Expand Up @@ -1162,6 +1172,25 @@ func testBodyBindingUseNumber2(t *testing.T, b Binding, name, path, badPath, bod
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) {
assert.Equal(t, name, b.Name())

Expand Down
9 changes: 9 additions & 0 deletions binding/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ import (
// interface{} as a Number instead of as a float64.
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{}

func (jsonBinding) Name() string {
Expand All @@ -40,6 +46,9 @@ func decodeJSON(r io.Reader, obj interface{}) error {
if EnableDecoderUseNumber {
decoder.UseNumber()
}
if EnableDecoderDisallowUnknownFields {
decoder.DisallowUnknownFields()
}
if err := decoder.Decode(obj); err != nil {
return err
}
Expand Down
8 changes: 7 additions & 1 deletion mode.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,18 @@ func DisableBindValidation() {
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.
func EnableJsonDecoderUseNumber() {
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.
func Mode() string {
return modeName
Expand Down
6 changes: 6 additions & 0 deletions mode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,9 @@ func TestEnableJsonDecoderUseNumber(t *testing.T) {
EnableJsonDecoderUseNumber()
assert.True(t, binding.EnableDecoderUseNumber)
}

func TestEnableJsonDecoderDisallowUnknownFields(t *testing.T) {
assert.False(t, binding.EnableDecoderDisallowUnknownFields)
EnableJsonDecoderDisallowUnknownFields()
assert.True(t, binding.EnableDecoderDisallowUnknownFields)
}

0 comments on commit f38c30a

Please sign in to comment.