feat(binding/json): check validity when bind json

Signed-off-by: demoManito <1430482733@qq.com>
This commit is contained in:
demoManito 2024-05-29 19:26:56 +08:00
parent 334160bab7
commit 563f4f606f
6 changed files with 46 additions and 2 deletions

View File

@ -13,6 +13,11 @@ import (
"github.com/gin-gonic/gin/internal/json"
)
var (
// ErrInvalidJSON invalid json
ErrInvalidJSON = errors.New("invalid JSON")
)
// EnableDecoderUseNumber is used to call the UseNumber method on the JSON
// Decoder instance. UseNumber causes the Decoder to unmarshal a number into an
// any as a Number instead of as a float64.
@ -34,10 +39,19 @@ func (jsonBinding) Bind(req *http.Request, obj any) error {
if req == nil || req.Body == nil {
return errors.New("invalid request")
}
return decodeJSON(req.Body, obj)
body, _ := io.ReadAll(req.Body)
ok := json.Valid(body)
if !ok {
return ErrInvalidJSON
}
return decodeJSON(bytes.NewReader(body), obj)
}
func (jsonBinding) BindBody(body []byte, obj any) error {
ok := json.Valid(body)
if !ok {
return ErrInvalidJSON
}
return decodeJSON(bytes.NewReader(body), obj)
}

View File

@ -5,6 +5,8 @@
package binding
import (
"bytes"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
@ -18,6 +20,9 @@ func TestJSONBindingBindBody(t *testing.T) {
err := jsonBinding{}.BindBody([]byte(`{"foo": "FOO"}`), &s)
require.NoError(t, err)
assert.Equal(t, "FOO", s.Foo)
err = jsonBinding{}.BindBody([]byte(`{"foo": "FOO}`), &s)
assert.Equal(t, ErrInvalidJSON, err)
}
func TestJSONBindingBindBodyMap(t *testing.T) {
@ -27,4 +32,21 @@ func TestJSONBindingBindBodyMap(t *testing.T) {
assert.Len(t, s, 2)
assert.Equal(t, "FOO", s["foo"])
assert.Equal(t, "world", s["hello"])
err = jsonBinding{}.BindBody([]byte(`{"foo": "FOO","hello":"world}`), &s)
assert.Equal(t, ErrInvalidJSON, err)
}
func TestTestJSONBindingBind(t *testing.T) {
var s struct {
Foo string `json:"foo"`
}
req, _ := http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`{"foo":"FOO"}`))
err := jsonBinding{}.Bind(req, &s)
require.NoError(t, err)
assert.Equal(t, "FOO", s.Foo)
req, _ = http.NewRequest(http.MethodPost, "/", bytes.NewBufferString(`{"foo":"FOO}`))
err = jsonBinding{}.Bind(req, &s)
assert.Equal(t, ErrInvalidJSON, err)
}

View File

@ -6,7 +6,7 @@
package json
import json "github.com/goccy/go-json"
import "github.com/goccy/go-json"
var (
// Marshal is exported by gin/json package.
@ -19,4 +19,6 @@ var (
NewDecoder = json.NewDecoder
// NewEncoder is exported by gin/json package.
NewEncoder = json.NewEncoder
// Valid is exported by gin/json package.
Valid = json.Valid
)

View File

@ -19,4 +19,6 @@ var (
NewDecoder = json.NewDecoder
// NewEncoder is exported by gin/json package.
NewEncoder = json.NewEncoder
// Valid is exported by gin/json package.
Valid = json.Valid
)

View File

@ -20,4 +20,6 @@ var (
NewDecoder = json.NewDecoder
// NewEncoder is exported by gin/json package.
NewEncoder = json.NewEncoder
// Valid is exported by gin/json package.
Valid = json.Valid
)

View File

@ -20,4 +20,6 @@ var (
NewDecoder = json.NewDecoder
// NewEncoder is exported by gin/json package.
NewEncoder = json.NewEncoder
// Valid is exported by gin/json package.
Valid = json.Valid
)