]> Cypherpunks repositories - gostls13.git/commitdiff
mime: handling invalid mime media parameters
authorAlexey Neganov <neganovalexey@gmail.com>
Tue, 14 Mar 2017 18:11:42 +0000 (21:11 +0300)
committerIan Lance Taylor <iant@golang.org>
Fri, 17 Mar 2017 13:59:31 +0000 (13:59 +0000)
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 <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/mime/mediatype.go
src/mime/mediatype_test.go

index 75cc90310f146c96b4707ed3f30a21181299edce..5557672b3d09f52545896345b07255a02303ed1f 100644 (file)
@@ -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
index c5fc906d6afe4bd12649bd7803a074c56f512499..3ba8ee18d5d92fb31d4b649684505a921e78b6b5 100644 (file)
@@ -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/<script>alert</script>", "mime: expected token after slash"},
-       {"bogus/bogus<script>alert</script>", "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/<script>alert</script>", "", "mime: expected token after slash"},
+       {"bogus/bogus<script>alert</script>", "", "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)
                }
        }
 }