Skip to content

Commit cb71b00

Browse files
authored
Sanitize 0x7F in Content-Disposition filename (#47549)
* Sanitize 0x7F in Content-Disposition filename We were using the ASCII boundaries, but it looks like we should have been using the ISO-8859 boundaries. Fixes #47027 * Update GetHeaderValue_Produces_Correct_ContentDisposition baseline
1 parent 812432f commit cb71b00

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

src/Http/Headers/src/ContentDispositionHeaderValue.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ private static StringSegment Sanitize(StringSegment input)
509509
for (int i = 0; i < result.Length; i++)
510510
{
511511
var c = result[i];
512-
if ((int)c > 0x7f || (int)c < 0x20)
512+
if ((int)c >= 0x7f || (int)c < 0x20)
513513
{
514514
c = '_'; // Replace out-of-range characters
515515
}
@@ -530,12 +530,12 @@ private static bool IsQuoted(StringSegment value)
530530
&& value.EndsWith("\"", StringComparison.Ordinal);
531531
}
532532

533-
// tspecials are required to be in a quoted string. Only non-ascii needs to be encoded.
533+
// tspecials are required to be in a quoted string. Only non-ascii and control characters need to be encoded.
534534
private static bool RequiresEncoding(StringSegment input)
535535
{
536536
Contract.Assert(input != null);
537537

538-
return input.AsSpan().IndexOfAnyExceptInRange((char)0x20, (char)0x7f) >= 0;
538+
return input.AsSpan().IndexOfAnyExceptInRange((char)0x20, (char)0x7e) >= 0;
539539
}
540540

541541
// Encode using MIME encoding

src/Http/Headers/test/ContentDispositionHeaderValueTest.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,16 @@ public void FileNameStar_UnknownOrBadEncoding_PropertyFails()
238238
[InlineData("FileName.bat", "FileName.bat")]
239239
[InlineData("FileÃName.bat", "File_Name.bat")]
240240
[InlineData("File\nName.bat", "File_Name.bat")]
241+
[InlineData("File\x19Name.bat", "File_Name.bat")]
242+
[InlineData("File\x20Name.bat", "File\x20Name.bat")] // First unsanitized
243+
[InlineData("File\x7eName.bat", "File\x7eName.bat")] // Last unsanitized
244+
[InlineData("File\x7fName.bat", "File_Name.bat")]
241245
public void SetHttpFileName_ShouldSanitizeFileNameWhereNeeded(string httpFileName, string expectedFileName)
242246
{
243247
var contentDisposition = new ContentDispositionHeaderValue("inline");
244248
contentDisposition.SetHttpFileName(httpFileName);
245249
Assert.Equal(expectedFileName, contentDisposition.FileName);
250+
Assert.Equal(httpFileName, contentDisposition.FileNameStar); // Should roundtrip through FileNameStar encoding
246251
}
247252

248253
[Fact]

src/Mvc/Mvc.Core/test/FileResultHelperTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ public static TheoryData<string, string> ContentDispositionControlCharactersData
198198
data.Add(char.ConvertFromUtf32(i), $"attachment; filename=_; filename*=UTF-8''%{i:X2}");
199199
}
200200

201-
data.Add(char.ConvertFromUtf32(127), $"attachment; filename=\"{char.ConvertFromUtf32(127)}\"; filename*=UTF-8''%7F");
201+
data.Add(char.ConvertFromUtf32(127), $"attachment; filename=_; filename*=UTF-8''%7F");
202202

203203
return data;
204204
}

0 commit comments

Comments
 (0)