Skip to content

Commit

Permalink
Fix for issue 6 in martini-contrib/csrf
Browse files Browse the repository at this point in the history
  • Loading branch information
mholt committed Aug 26, 2014
1 parent 1973905 commit 1928ed2
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 17 deletions.
25 changes: 14 additions & 11 deletions binding.go
Expand Up @@ -99,23 +99,26 @@ func MultipartForm(formStruct interface{}, ifacePtr ...interface{}) martini.Hand
ensureNotPointer(formStruct)
formStruct := reflect.New(reflect.TypeOf(formStruct))

// Workaround for multipart forms returning nil instead of an error
// when content is not multipart
// https://code.google.com/p/go/issues/detail?id=6334
multipartReader, err := req.MultipartReader()
if err != nil {
errors.Add([]string{}, DeserializationError, err.Error())
} else {
form, parseErr := multipartReader.ReadForm(MaxMemory)
if parseErr != nil {
errors.Add([]string{}, DeserializationError, parseErr.Error())
// This if check is necessary due to https://github.com/martini-contrib/csrf/issues/6
if req.MultipartForm == nil {
// Workaround for multipart forms returning nil instead of an error
// when content is not multipart; see https://code.google.com/p/go/issues/detail?id=6334
if multipartReader, err := req.MultipartReader(); err != nil {
// TODO: Cover this and the next error check with tests
errors.Add([]string{}, DeserializationError, err.Error())
} else {
form, parseErr := multipartReader.ReadForm(MaxMemory)
if parseErr != nil {
errors.Add([]string{}, DeserializationError, parseErr.Error())
}
req.MultipartForm = form
}
req.MultipartForm = form
}

mapForm(formStruct, req.MultipartForm.Value, req.MultipartForm.File, errors)
validateAndMap(formStruct, context, errors, ifacePtr...)
}

}

// Json is middleware to deserialize a JSON payload from the request
Expand Down
22 changes: 16 additions & 6 deletions multipart_test.go
Expand Up @@ -18,6 +18,12 @@ var multipartFormTestCases = []multipartFormTestCase{
shouldSucceed: true,
inputAndExpected: BlogPost{Post: Post{Title: "Glorious Post Title"}, Id: 1, Author: Person{Name: "Matt Holt"}},
},
{
description: "FormValue called before req.MultipartReader(); see https://github.com/martini-contrib/csrf/issues/6",
shouldSucceed: true,
callFormValueBefore: true,
inputAndExpected: BlogPost{Post: Post{Title: "Glorious Post Title"}, Id: 1, Author: Person{Name: "Matt Holt"}},
},
{
description: "Empty payload",
shouldSucceed: false,
Expand Down Expand Up @@ -89,6 +95,10 @@ func performMultipartFormTest(t *testing.T, binder handlerFunc, testCase multipa
panic(err)
}

if testCase.callFormValueBefore {
req.FormValue("foo")
}

m.ServeHTTP(httpRecorder, req)

switch httpRecorder.Code {
Expand All @@ -105,8 +115,7 @@ func makeMultipartPayload(testCase multipartFormTestCase) (*bytes.Buffer, *multi
writer := multipart.NewWriter(body)
if testCase.malformEncoding {
// TODO: Break the multipart form parser which is apparently impervious!!
// (Get it to return an error. I'm trying to get test coverage inside the
// code that handles this possibility...)
// (Get it to return an error. Trying to get 100% test coverage.)
body.Write([]byte(`--` + writer.Boundary() + `\nContent-Disposition: form-data; name="foo"\n\n--` + writer.Boundary() + `--`))
return body, writer
} else {
Expand All @@ -126,9 +135,10 @@ func makeMultipartPayload(testCase multipartFormTestCase) (*bytes.Buffer, *multi

type (
multipartFormTestCase struct {
description string
shouldSucceed bool
inputAndExpected BlogPost
malformEncoding bool
description string
shouldSucceed bool
inputAndExpected BlogPost
malformEncoding bool
callFormValueBefore bool
}
)

0 comments on commit 1928ed2

Please sign in to comment.