Skip to content

Commit 8350b94

Browse files
authored
[7.0] Limit the hpack buffer resize (#44644)
* Limit the hpack buffer resize #44643 * More resizes
1 parent 761eec9 commit 8350b94

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

src/Shared/runtime/Http2/Hpack/HPackDecoder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ private void OnStringLength(int length, State nextState)
577577
throw new HPackDecodingException(SR.Format(SR.net_http_headers_exceeded_length, _maxHeadersLength));
578578
}
579579

580-
_stringOctets = new byte[Math.Max(length, _stringOctets.Length * 2)];
580+
_stringOctets = new byte[Math.Max(length, Math.Min(_stringOctets.Length * 2, _maxHeadersLength))];
581581
}
582582

583583
_stringLength = length;
@@ -625,7 +625,7 @@ private void EnsureStringCapacity(ref byte[] dst)
625625
{
626626
if (dst.Length < _stringLength)
627627
{
628-
dst = new byte[Math.Max(_stringLength, dst.Length * 2)];
628+
dst = new byte[Math.Max(_stringLength, Math.Min(dst.Length * 2, _maxHeadersLength))];
629629
}
630630
}
631631

src/Shared/test/Shared.Tests/runtime/Http2/HPackDecoderTest.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,41 @@ public void DecodesStringLength_LimitConfigurable()
493493
Assert.Equal(string8193, _handler.DecodedHeaders[string8193]);
494494
}
495495

496+
[Fact]
497+
public void DecodesStringLength_ExceedsLimit_Throws()
498+
{
499+
HPackDecoder decoder = new HPackDecoder(DynamicTableInitialMaxSize, MaxHeaderFieldSize + 1);
500+
string string8191 = new string('a', MaxHeaderFieldSize - 1);
501+
string string8193 = new string('a', MaxHeaderFieldSize + 1);
502+
string string8194 = new string('a', MaxHeaderFieldSize + 2);
503+
504+
var bytes = new byte[3];
505+
var success = IntegerEncoder.Encode(8194, 7, bytes, out var written);
506+
507+
byte[] encoded = _literalHeaderFieldWithoutIndexingNewName
508+
.Concat(new byte[] { 0x7f, 0x80, 0x3f }) // 8191 encoded with 7-bit prefix, no Huffman encoding
509+
.Concat(Encoding.ASCII.GetBytes(string8191))
510+
.Concat(new byte[] { 0x7f, 0x80, 0x3f }) // 8191 encoded with 7-bit prefix, no Huffman encoding
511+
.Concat(Encoding.ASCII.GetBytes(string8191))
512+
.Concat(_literalHeaderFieldWithoutIndexingNewName)
513+
.Concat(new byte[] { 0x7f, 0x82, 0x3f }) // 8193 encoded with 7-bit prefix, no Huffman encoding
514+
.Concat(Encoding.ASCII.GetBytes(string8193))
515+
.Concat(new byte[] { 0x7f, 0x82, 0x3f }) // 8193 encoded with 7-bit prefix, no Huffman encoding
516+
.Concat(Encoding.ASCII.GetBytes(string8193))
517+
.Concat(_literalHeaderFieldWithoutIndexingNewName)
518+
.Concat(new byte[] { 0x7f, 0x83, 0x3f }) // 8194 encoded with 7-bit prefix, no Huffman encoding
519+
.Concat(Encoding.ASCII.GetBytes(string8194))
520+
.Concat(new byte[] { 0x7f, 0x83, 0x3f }) // 8194 encoded with 7-bit prefix, no Huffman encoding
521+
.Concat(Encoding.ASCII.GetBytes(string8194))
522+
.ToArray();
523+
524+
var ex = Assert.Throws<HPackDecodingException>(() => decoder.Decode(encoded, endHeaders: true, handler: _handler));
525+
Assert.Equal(SR.Format(SR.net_http_headers_exceeded_length, MaxHeaderFieldSize + 1), ex.Message);
526+
Assert.Equal(string8191, _handler.DecodedHeaders[string8191]);
527+
Assert.Equal(string8193, _handler.DecodedHeaders[string8193]);
528+
Assert.False(_handler.DecodedHeaders.ContainsKey(string8194));
529+
}
530+
496531
[Fact]
497532
public void DecodesStringLength_IndividualBytes()
498533
{

0 commit comments

Comments
 (0)