diff options
| author | Shulhan <m.shulhan@gmail.com> | 2023-05-11 15:23:39 +0700 |
|---|---|---|
| committer | Shulhan <m.shulhan@gmail.com> | 2023-05-11 16:16:12 +0700 |
| commit | 9d1afbf308f2ac382f364f935867ce0cef0a3573 (patch) | |
| tree | f4e3818d1b44329dea9a5a7f4a8021f0edeb087d | |
| parent | a2838ec5f20b56e94a18c873ab4b68397355e214 (diff) | |
| download | go-ms-fix-multipart-readform.tar.xz | |
mime/multipart: fix ReadForm always return (nil,io.EOF)ms-fix-multipart-readform
Previously, the condition err == io.EOF in readForm will never true and
break; it always goes to the second condition, err != nil, which
cause the returned ReadForm always nil with err is io.EOF.
As the test, we use the example with body almost similar to
ExampleNewReader with header contains "Content-Disposition:form-data".
Change-Id: I7268f45bb26eafb7f1e6e471b86eec681dde99f7
| -rw-r--r-- | src/mime/multipart/example_test.go | 40 | ||||
| -rw-r--r-- | src/mime/multipart/formdata.go | 2 | ||||
| -rw-r--r-- | src/mime/multipart/multipart.go | 3 | ||||
| -rw-r--r-- | src/net/http/request_test.go | 11 |
4 files changed, 50 insertions, 6 deletions
diff --git a/src/mime/multipart/example_test.go b/src/mime/multipart/example_test.go index fe154ac4f6..7a22ff789e 100644 --- a/src/mime/multipart/example_test.go +++ b/src/mime/multipart/example_test.go @@ -50,3 +50,43 @@ func ExampleNewReader() { // Part "one": "A section" // Part "two": "And another" } + +func ExampleReader_ReadForm() { + body := strings.NewReader( + "--foo\r\nContent-Disposition: form-data; name=\"field1\"\r\n\r\n" + + "Value of field.\r\n" + + "--foo\r\nContent-Disposition: form-data; name=\"file1\"; filename=\"file1.txt\"\r\n\r\n" + + "Value of file1.\r\n" + + "--foo--\r\n") + + mr := multipart.NewReader(body, "foo") + form, err := mr.ReadForm(0) + if err != nil { + log.Fatal(err) + } + + for name, val := range form.Value { + fmt.Printf("Form.Value %q: %q\n", name, val) + } + for name, listHeader := range form.File { + for _, hdr := range listHeader { + file, err := hdr.Open() + if err != nil { + log.Fatal(err) + } + content, err := io.ReadAll(file) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Form.File %q:\n", name) + fmt.Printf(" Filename: %q\n", hdr.Filename) + fmt.Printf(" Content: %q\n", content) + } + } + + // Output: + // Form.Value "field1": ["Value of field."] + // Form.File "file1": + // Filename: "file1.txt" + // Content: "Value of file1." +} diff --git a/src/mime/multipart/formdata.go b/src/mime/multipart/formdata.go index f8258a961c..f2ca0118a6 100644 --- a/src/mime/multipart/formdata.go +++ b/src/mime/multipart/formdata.go @@ -108,7 +108,7 @@ func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) { var copyBuf []byte for { p, err := r.nextPart(false, maxMemoryBytes, maxHeaders) - if err == io.EOF { + if errors.Is(err, io.EOF) { break } if err != nil { diff --git a/src/mime/multipart/multipart.go b/src/mime/multipart/multipart.go index da1f45810e..c570f1d7e2 100644 --- a/src/mime/multipart/multipart.go +++ b/src/mime/multipart/multipart.go @@ -30,6 +30,7 @@ package multipart import ( "bufio" "bytes" + "errors" "fmt" "internal/godebug" "io" @@ -392,7 +393,7 @@ func (r *Reader) nextPart(rawPart bool, maxMIMEHeaderSize, maxMIMEHeaders int64) for { line, err := r.bufReader.ReadSlice('\n') - if err == io.EOF && r.isFinalBoundary(line) { + if errors.Is(err, io.EOF) && r.isFinalBoundary(line) { // If the buffer ends in "--boundary--" without the // trailing "\r\n", ReadSlice will return an error // (since it's missing the '\n'), but this is a valid diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go index 78b968f23c..c952b0ad26 100644 --- a/src/net/http/request_test.go +++ b/src/net/http/request_test.go @@ -251,14 +251,17 @@ func TestParseMultipartForm(t *testing.T) { Body: io.NopCloser(new(bytes.Buffer)), } err := req.ParseMultipartForm(25) - if err == nil { - t.Error("expected multipart EOF, got nil") + if err != nil { + t.Errorf("expecting nil, got %v", err) } + // Reset to allow the call to multipartReader. + req.MultipartForm = nil + req.Header = Header{"Content-Type": {"text/plain"}} err = req.ParseMultipartForm(25) - if err != ErrNotMultipart { - t.Error("expected ErrNotMultipart for text/plain") + if !errors.Is(err, ErrNotMultipart) { + t.Errorf("expected ErrNotMultipart for text/plain, got %v", err) } } |
