mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-08-24 21:17:31 +00:00
fix: don't rely on content length header for optional json binding
This commit is contained in:
@@ -33,17 +33,13 @@ func BindJSON(c *gin.Context, value any) error {
|
||||
|
||||
// BindOptionalJSON accepts an empty body while normalizing valid input and classifying malformed JSON as invalid input
|
||||
func BindOptionalJSON(c *gin.Context, value any) error {
|
||||
if c.Request.ContentLength == 0 {
|
||||
return nil
|
||||
}
|
||||
if err := requireJSONContentType(c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := c.ShouldBindJSON(value)
|
||||
if errors.Is(err, io.EOF) {
|
||||
return nil
|
||||
}
|
||||
if contentTypeErr := requireJSONContentType(c); contentTypeErr != nil {
|
||||
return contentTypeErr
|
||||
}
|
||||
if err = classifyBindingError(err); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -97,6 +97,32 @@ func TestBindJSONAcceptsStructuredJSONContentType(t *testing.T) {
|
||||
require.Equal(t, "admin", input.Name)
|
||||
}
|
||||
|
||||
func TestBindOptionalJSONDoesNotRelyOnContentLength(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
contentLength int64
|
||||
}{
|
||||
{name: "zero", contentLength: 0},
|
||||
{name: "unknown", contentLength: -1},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
c, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/", strings.NewReader(`{"secret":"custom-secret"}`))
|
||||
c.Request.ContentLength = test.contentLength
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
var input struct {
|
||||
Secret string `json:"secret"`
|
||||
}
|
||||
err := BindOptionalJSON(c, &input)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "custom-secret", input.Secret)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormFileClassifiesMissingField(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
c, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
|
||||
Reference in New Issue
Block a user