Commit a3f99dc4 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

mime: don't accept single-quoted strings in media type parameter values

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 90e4ece3
(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 #11291

Change-Id: I6de58009dd47dcabb120b017245d237cb7b1e89a
Reviewed-on: https://go-review.googlesource.com/17136Reviewed-by: default avatarRuss Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 1dae4737
......@@ -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
......
......@@ -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")},
......@@ -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) {
......
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