Skip to content

Commit 0a001b8

Browse files
committed
Test invalid Latin1 in all positions
1 parent 394be7b commit 0a001b8

File tree

1 file changed

+49
-16
lines changed

1 file changed

+49
-16
lines changed

src/Servers/Kestrel/Core/test/HttpRequestHeadersTests.cs

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -426,28 +426,61 @@ public void ValueReuseNeverWhenNotAscii(bool reuseValue, KnownHeader header)
426426
[MemberData(nameof(KnownRequestHeaders))]
427427
public void ValueReuseLatin1NotConfusedForUtf16AndStillRejected(bool reuseValue, KnownHeader header)
428428
{
429-
const string HeaderValueUtf16Latin1CrossOver = "Hello \u00a3";
430-
431429
var headers = new HttpRequestHeaders(reuseHeaderValues: reuseValue);
432-
headers.Reset();
433430

434-
var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
435-
var prevSpan = Encoding.UTF8.GetBytes(HeaderValueUtf16Latin1CrossOver).AsSpan();
431+
var headerValue = new char[127]; // 64 + 32 + 16 + 8 + 4 + 2 + 1
432+
for (var i = 0; i < headerValue.Length; i++)
433+
{
434+
headerValue[i] = 'a';
435+
}
436436

437-
headers.Append(headerName, prevSpan);
438-
headers.OnHeadersComplete();
439-
var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();
437+
for (var i = 0; i < headerValue.Length; i++)
438+
{
439+
// Set non-ascii Latin char that is valid Utf16 when widened; but not a valid utf8 -> utf16 conversion.
440+
headerValue[i] = '\u00a3';
440441

441-
Assert.Equal(HeaderValueUtf16Latin1CrossOver, prevHeaderValue);
442-
Assert.NotSame(HeaderValueUtf16Latin1CrossOver, prevHeaderValue);
442+
for (var mode = 0; mode <= 1; mode++)
443+
{
444+
string headerValueUtf16Latin1CrossOver;
445+
if (mode == 0)
446+
{
447+
// Full length
448+
headerValueUtf16Latin1CrossOver = new string(headerValue);
449+
}
450+
else
451+
{
452+
// Truncated length (to ensure different paths from changing lengths in matching)
453+
headerValueUtf16Latin1CrossOver = new string(headerValue.AsSpan().Slice(0, i + 1));
454+
}
443455

444-
headers.Reset();
456+
headers.Reset();
445457

446-
Assert.Throws<InvalidOperationException>(() => {
447-
var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
448-
var nextSpan = Encoding.GetEncoding("iso-8859-1").GetBytes(HeaderValueUtf16Latin1CrossOver).AsSpan();
449-
headers.Append(headerName, nextSpan);
450-
});
458+
var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
459+
var prevSpan = Encoding.UTF8.GetBytes(headerValueUtf16Latin1CrossOver).AsSpan();
460+
461+
headers.Append(headerName, prevSpan);
462+
headers.OnHeadersComplete();
463+
var prevHeaderValue = ((IHeaderDictionary)headers)[header.Name].ToString();
464+
465+
Assert.Equal(headerValueUtf16Latin1CrossOver, prevHeaderValue);
466+
Assert.NotSame(headerValueUtf16Latin1CrossOver, prevHeaderValue);
467+
468+
headers.Reset();
469+
470+
Assert.Throws<InvalidOperationException>(() =>
471+
{
472+
var headerName = Encoding.ASCII.GetBytes(header.Name).AsSpan();
473+
var nextSpan = Encoding.GetEncoding("iso-8859-1").GetBytes(headerValueUtf16Latin1CrossOver).AsSpan();
474+
475+
Assert.False(nextSpan.SequenceEqual(Encoding.ASCII.GetBytes(headerValueUtf16Latin1CrossOver)));
476+
477+
headers.Append(headerName, nextSpan);
478+
});
479+
}
480+
481+
// Reset back to Ascii
482+
headerValue[i] = 'a';
483+
}
451484
}
452485

453486
[Fact]

0 commit comments

Comments
 (0)