Commit a6293995 authored by Ian Lance Taylor's avatar Ian Lance Taylor

mime/multipart: quote boundary in Content-Type if necessary

Fixes #26532

Change-Id: Ic086c90503c7b24982f947c828c7ccf016ddbf69
Reviewed-on: https://go-review.googlesource.com/c/154120
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 784d8109
...@@ -72,7 +72,13 @@ func (w *Writer) SetBoundary(boundary string) error { ...@@ -72,7 +72,13 @@ func (w *Writer) SetBoundary(boundary string) error {
// FormDataContentType returns the Content-Type for an HTTP // FormDataContentType returns the Content-Type for an HTTP
// multipart/form-data with this Writer's Boundary. // multipart/form-data with this Writer's Boundary.
func (w *Writer) FormDataContentType() string { func (w *Writer) FormDataContentType() string {
return "multipart/form-data; boundary=" + w.boundary b := w.boundary
// We must quote the boundary if it contains any of the
// tspecials characters defined by RFC 2045, or space.
if strings.ContainsAny(b, `()<>@,;:\"/[]?= `) {
b = `"` + b + `"`
}
return "multipart/form-data; boundary=" + b
} }
func randomBoundary() string { func randomBoundary() string {
......
...@@ -7,6 +7,7 @@ package multipart ...@@ -7,6 +7,7 @@ package multipart
import ( import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"mime"
"net/textproto" "net/textproto"
"strings" "strings"
"testing" "testing"
...@@ -94,6 +95,7 @@ func TestWriterSetBoundary(t *testing.T) { ...@@ -94,6 +95,7 @@ func TestWriterSetBoundary(t *testing.T) {
{"my-separator", true}, {"my-separator", true},
{"with space", true}, {"with space", true},
{"badspace ", false}, {"badspace ", false},
{"(boundary)", true},
} }
for i, tt := range tests { for i, tt := range tests {
var b bytes.Buffer var b bytes.Buffer
...@@ -107,6 +109,17 @@ func TestWriterSetBoundary(t *testing.T) { ...@@ -107,6 +109,17 @@ func TestWriterSetBoundary(t *testing.T) {
if got != tt.b { if got != tt.b {
t.Errorf("boundary = %q; want %q", got, tt.b) t.Errorf("boundary = %q; want %q", got, tt.b)
} }
ct := w.FormDataContentType()
mt, params, err := mime.ParseMediaType(ct)
if err != nil {
t.Errorf("could not parse Content-Type %q: %v", ct, err)
} else if mt != "multipart/form-data" {
t.Errorf("unexpected media type %q; want %q", mt, "multipart/form-data")
} else if b := params["boundary"]; b != tt.b {
t.Errorf("unexpected boundary parameter %q; want %q", b, tt.b)
}
w.Close() w.Close()
wantSub := "\r\n--" + tt.b + "--\r\n" wantSub := "\r\n--" + tt.b + "--\r\n"
if got := b.String(); !strings.Contains(got, wantSub) { if got := b.String(); !strings.Contains(got, wantSub) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment