From: Alexey Neganov Date: Tue, 14 Mar 2017 18:11:42 +0000 (+0300) Subject: mime: handling invalid mime media parameters X-Git-Tag: go1.9beta1~1128 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b9f6b22a0100716db1f196a395f9ded8456337f8;p=gostls13.git mime: handling invalid mime media parameters Sometimes it's necessary to deal with emails that do not follow the specification; in particular, it's possible to download such email via gmail. When the existing implementation handle invalid mime media parameters, it returns nils and error, although there is a valid media type, which may be returned. If this behavior changes, it may not affect any existing programs, but it will help to parse some emails. Fixes #19498 Change-Id: Ieb2fdbddfd93857faee941d2aa49d59e286d57fd Reviewed-on: https://go-review.googlesource.com/38190 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot --- diff --git a/src/mime/mediatype.go b/src/mime/mediatype.go index 75cc90310f..5557672b3d 100644 --- a/src/mime/mediatype.go +++ b/src/mime/mediatype.go @@ -94,11 +94,19 @@ func checkMediaTypeDisposition(s string) error { return nil } +// ErrInvalidMediaParameter is returned by ParseMediaType if +// the media type value was found but there was an error parsing +// the optional parameters +var ErrInvalidMediaParameter = errors.New("mime: invalid media parameter") + // ParseMediaType parses a media type value and any optional // parameters, per RFC 1521. Media types are the values in // Content-Type and Content-Disposition headers (RFC 2183). // On success, ParseMediaType returns the media type converted // to lowercase and trimmed of white space and a non-nil map. +// If there is an error parsing the optional parameter, +// the media type will be returned along with the error +// ErrInvalidMediaParameter. // The returned map, params, maps from the lowercase // attribute to the attribute value with its case preserved. func ParseMediaType(v string) (mediatype string, params map[string]string, err error) { @@ -134,7 +142,7 @@ func ParseMediaType(v string) (mediatype string, params map[string]string, err e return } // Parse error. - return "", nil, errors.New("mime: invalid media parameter") + return mediatype, nil, ErrInvalidMediaParameter } pmap := params diff --git a/src/mime/mediatype_test.go b/src/mime/mediatype_test.go index c5fc906d6a..3ba8ee18d5 100644 --- a/src/mime/mediatype_test.go +++ b/src/mime/mediatype_test.go @@ -253,13 +253,18 @@ func TestParseMediaType(t *testing.T) { type badMediaTypeTest struct { in string + mt string err string } var badMediaTypeTests = []badMediaTypeTest{ - {"bogus ;=========", "mime: invalid media parameter"}, - {"bogus/", "mime: expected token after slash"}, - {"bogus/bogus", "mime: unexpected content after media subtype"}, + {"bogus ;=========", "bogus", "mime: invalid media parameter"}, + // The following example is from real email delivered by gmail (error: missing semicolon) + // and it is there to check behavior described in #19498 + {"application/pdf; x-mac-type=\"3F3F3F3F\"; x-mac-creator=\"3F3F3F3F\" name=\"a.pdf\";", + "application/pdf", "mime: invalid media parameter"}, + {"bogus/", "", "mime: expected token after slash"}, + {"bogus/bogus", "", "mime: unexpected content after media subtype"}, } func TestParseMediaTypeBogus(t *testing.T) { @@ -275,8 +280,11 @@ func TestParseMediaTypeBogus(t *testing.T) { if params != nil { t.Errorf("ParseMediaType(%q): got non-nil params on error", tt.in) } - if mt != "" { - t.Errorf("ParseMediaType(%q): got non-empty media type string on error", tt.in) + if err != ErrInvalidMediaParameter && mt != "" { + t.Errorf("ParseMediaType(%q): got unexpected non-empty media type string", tt.in) + } + if err == ErrInvalidMediaParameter && mt != tt.mt { + t.Errorf("ParseMediaType(%q): in case of invalid parameters: expected type %q, got %q", tt.in, tt.mt, mt) } } }