Skip to content

Commit

Permalink
mime: don't accept single-quoted strings in media type parameter values
Browse files Browse the repository at this point in the history
Fix an old bug where media type parameter values could be escaped by
either double quotes (per the spec) or single quotes (due to my bug).

The original bug was introduced by me in git rev 90e4ece
(https://golang.org/cl/4430049) in April 2011 when adding more tests
from http://greenbytes.de/tech/tc2231/ and misinterpreting the
expected value of test "attwithfntokensq" and not apparently thinking
about it enough.

No known spec or existing software produces or expects single quotes
around values. In fact, it would have be a parsing ambiguity if it
were allowed: the string `a=', b='` could parse as two keys "a" and
"b" both with value "'", or it could be parse as a single key "a" with
value "', b=".

Fixes golang#11291

Change-Id: I6de58009dd47dcabb120b017245d237cb7b1e89a
Reviewed-on: https://go-review.googlesource.com/17136
Reviewed-by: Russ Cox <[email protected]>
Run-TryBot: Brad Fitzpatrick <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
  • Loading branch information
bradfitz committed Dec 1, 2015
1 parent 1dae473 commit a3f99dc
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 8 deletions.
13 changes: 6 additions & 7 deletions src/mime/mediatype.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,24 +237,23 @@ func consumeToken(v string) (token, rest string) {
// quoted-string) and the rest of the string. On failure, returns
// ("", v).
func consumeValue(v string) (value, rest string) {
if !strings.HasPrefix(v, `"`) && !strings.HasPrefix(v, `'`) {
if v == "" {
return
}
if v[0] != '"' {
return consumeToken(v)
}

leadQuote := rune(v[0])

// parse a quoted-string
rest = v[1:] // consume the leading quote
buffer := new(bytes.Buffer)
var idx int
var r rune
var nextIsLiteral bool
for idx, r = range rest {
for idx, r := range rest {
switch {
case nextIsLiteral:
buffer.WriteRune(r)
nextIsLiteral = false
case r == leadQuote:
case r == '"':
return buffer.String(), rest[idx+1:]
case r == '\\':
nextIsLiteral = true
Expand Down
3 changes: 2 additions & 1 deletion src/mime/mediatype_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func TestParseMediaType(t *testing.T) {
m("filename", "foo.html")},
{`attachment; filename='foo.html'`,
"attachment",
m("filename", "foo.html")},
m("filename", "'foo.html'")},
{`attachment; filename="foo-%41.html"`,
"attachment",
m("filename", "foo-%41.html")},
Expand Down Expand Up @@ -294,6 +294,7 @@ var formatTests = []formatTest{
{"foo/BAR", map[string]string{"bad attribute": "baz"}, ""},
{"foo/BAR", map[string]string{"nonascii": "not an ascii character: ä"}, ""},
{"foo/bar", map[string]string{"a": "av", "b": "bv", "c": "cv"}, "foo/bar; a=av; b=bv; c=cv"},
{"foo/bar", map[string]string{"0": "'", "9": "'"}, "foo/bar; 0='; 9='"},
}

func TestFormatMediaType(t *testing.T) {
Expand Down

0 comments on commit a3f99dc

Please sign in to comment.