HPACK circular overflow #12190 (#12782)

This commit is contained in:
Chris Ross 2019-08-01 14:30:32 -07:00 committed by GitHub
parent 001b54f42e
commit 59f6b852c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 2 deletions

View File

@ -5,6 +5,8 @@ using System;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack
{
// The dynamic table is defined as a queue where items are inserted at the front and removed from the back.
// It's implemented as a circular buffer that appends to the end and trims from the front. Thus index are reversed.
internal class DynamicTable
{
private HeaderField[] _buffer;
@ -35,7 +37,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack
throw new IndexOutOfRangeException();
}
return _buffer[_insertIndex == 0 ? _buffer.Length - 1 : _insertIndex - index - 1];
var modIndex = _insertIndex - index - 1;
if (modIndex < 0)
{
modIndex += _buffer.Length;
}
return _buffer[modIndex];
}
}

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@ -58,6 +58,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
VerifyTableEntries(dynamicTable, _header2, _header1);
}
[Fact]
public void WrapsAroundBuffer()
{
var header3 = new HeaderField(Encoding.ASCII.GetBytes("header-3"), Encoding.ASCII.GetBytes("value3"));
var header4 = new HeaderField(Encoding.ASCII.GetBytes("header-4"), Encoding.ASCII.GetBytes("value4"));
// Make the table small enough that the circular buffer kicks in.
var dynamicTable = new DynamicTable(HeaderField.RfcOverhead * 3);
dynamicTable.Insert(header4.Name, header4.Value);
dynamicTable.Insert(header3.Name, header3.Value);
dynamicTable.Insert(_header2.Name, _header2.Value);
dynamicTable.Insert(_header1.Name, _header1.Value);
VerifyTableEntries(dynamicTable, _header1, _header2);
}
[Fact]
public void ThrowsIndexOutOfRangeException()
{