Skip to content

Commit a3f99dc

Browse files
committed
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 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 #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>
1 parent 1dae473 commit a3f99dc

File tree

2 files changed

+8
-8
lines changed

2 files changed

+8
-8
lines changed

src/mime/mediatype.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -237,24 +237,23 @@ func consumeToken(v string) (token, rest string) {
237237
// quoted-string) and the rest of the string. On failure, returns
238238
// ("", v).
239239
func consumeValue(v string) (value, rest string) {
240-
if !strings.HasPrefix(v, `"`) && !strings.HasPrefix(v, `'`) {
240+
if v == "" {
241+
return
242+
}
243+
if v[0] != '"' {
241244
return consumeToken(v)
242245
}
243246

244-
leadQuote := rune(v[0])
245-
246247
// parse a quoted-string
247248
rest = v[1:] // consume the leading quote
248249
buffer := new(bytes.Buffer)
249-
var idx int
250-
var r rune
251250
var nextIsLiteral bool
252-
for idx, r = range rest {
251+
for idx, r := range rest {
253252
switch {
254253
case nextIsLiteral:
255254
buffer.WriteRune(r)
256255
nextIsLiteral = false
257-
case r == leadQuote:
256+
case r == '"':
258257
return buffer.String(), rest[idx+1:]
259258
case r == '\\':
260259
nextIsLiteral = true

src/mime/mediatype_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ func TestParseMediaType(t *testing.T) {
159159
m("filename", "foo.html")},
160160
{`attachment; filename='foo.html'`,
161161
"attachment",
162-
m("filename", "foo.html")},
162+
m("filename", "'foo.html'")},
163163
{`attachment; filename="foo-%41.html"`,
164164
"attachment",
165165
m("filename", "foo-%41.html")},
@@ -294,6 +294,7 @@ var formatTests = []formatTest{
294294
{"foo/BAR", map[string]string{"bad attribute": "baz"}, ""},
295295
{"foo/BAR", map[string]string{"nonascii": "not an ascii character: ä"}, ""},
296296
{"foo/bar", map[string]string{"a": "av", "b": "bv", "c": "cv"}, "foo/bar; a=av; b=bv; c=cv"},
297+
{"foo/bar", map[string]string{"0": "'", "9": "'"}, "foo/bar; 0='; 9='"},
297298
}
298299

299300
func TestFormatMediaType(t *testing.T) {

0 commit comments

Comments
 (0)