From c88dd5dc02ab5dfc5f3323480dbdc3992834344f Mon Sep 17 00:00:00 2001 From: nick9822 Date: Fri, 4 Nov 2022 01:54:53 +0530 Subject: [PATCH] fix form empty field error when used with pipe (#1417) Co-authored-by: root --- http.go | 2 +- http_test.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/http.go b/http.go index 62ba30ffb6..4ef3744214 100644 --- a/http.go +++ b/http.go @@ -2001,7 +2001,7 @@ func writeBodyChunked(w *bufio.Writer, r io.Reader) error { n, err = r.Read(buf) if n == 0 { if err == nil { - panic("BUG: io.Reader returned 0, nil") + continue } if err == io.EOF { if err = writeChunk(w, buf[:0]); err != nil { diff --git a/http_test.go b/http_test.go index 60e7891818..52d8a670ab 100644 --- a/http_test.go +++ b/http_test.go @@ -2949,3 +2949,87 @@ func TestResponseBodyStreamErrorOnPanicDuringClose(t *testing.T) { t.Fatalf("unexpected error value, got: %+v.", e.Error()) } } + +func TestRequestMultipartFormPipeEmptyFormField(t *testing.T) { + t.Parallel() + + pr, pw := io.Pipe() + mw := multipart.NewWriter(pw) + + errs := make(chan error, 1) + + go func() { + defer func() { + err := mw.Close() + if err != nil { + errs <- err + } + err = pw.Close() + if err != nil { + errs <- err + } + close(errs) + }() + + if err := mw.WriteField("emptyField", ""); err != nil { + errs <- err + } + }() + + var b bytes.Buffer + bw := bufio.NewWriter(&b) + err := writeBodyChunked(bw, pr) + + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + for e := range errs { + t.Fatalf("unexpected error in goroutine multiwriter: %v", e) + } + + testRequestMultipartFormPipeEmptyFormField(t, mw.Boundary(), b.Bytes(), 1) +} + +func testRequestMultipartFormPipeEmptyFormField(t *testing.T, boundary string, formData []byte, partsCount int) []byte { + s := fmt.Sprintf("POST / HTTP/1.1\r\nHost: aaa\r\nContent-Type: multipart/form-data; boundary=%s\r\nTransfer-Encoding: chunked\r\n\r\n%s", + boundary, formData) + + var req Request + + r := bytes.NewBufferString(s) + br := bufio.NewReader(r) + if err := req.Read(br); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + f, err := req.MultipartForm() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + defer req.RemoveMultipartFormFiles() + + if len(f.File) > 0 { + t.Fatalf("unexpected files found in the multipart form: %d", len(f.File)) + } + + if len(f.Value) != partsCount { + t.Fatalf("unexpected number of values found: %d. Expecting %d", len(f.Value), partsCount) + } + + for k, vv := range f.Value { + if len(vv) != 1 { + t.Fatalf("unexpected number of values found for key=%q: %d. Expecting 1", k, len(vv)) + } + if k != "emptyField" { + t.Fatalf("unexpected key=%q. Expecting %q", k, "emptyField") + } + + v := vv[0] + if v != "" { + t.Fatalf("unexpected value=%q. expecting %q", v, "") + } + } + + return req.Body() +}