1
0
mirror of https://github.com/golang/go synced 2024-11-23 21:20:03 -07:00

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/17136
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Brad Fitzpatrick 2015-11-30 20:28:19 +00:00
parent 1dae47378c
commit a3f99dc4e9
2 changed files with 8 additions and 8 deletions

View File

@ -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

View File

@ -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) {