Fix a write past the end of buffer when IntegerEncoder encodes to multi-bytes and does not have sufficient room to do so. (#10914)
Add some basic asserts to constrain parameters to HPACK spec. Add some additional tests.
This commit is contained in:
parent
d3e90a7c07
commit
bc6f4b6034
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack
|
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack
|
||||||
{
|
{
|
||||||
|
|
@ -9,6 +10,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack
|
||||||
{
|
{
|
||||||
public static bool Encode(int i, int n, Span<byte> buffer, out int length)
|
public static bool Encode(int i, int n, Span<byte> buffer, out int length)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(i >= 0);
|
||||||
|
Debug.Assert(n >= 1 && n <= 8);
|
||||||
|
|
||||||
var j = 0;
|
var j = 0;
|
||||||
length = 0;
|
length = 0;
|
||||||
|
|
||||||
|
|
@ -37,7 +41,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack
|
||||||
{
|
{
|
||||||
buffer[j++] = (byte)(i % 128 + 128);
|
buffer[j++] = (byte)(i % 128 + 128);
|
||||||
|
|
||||||
if (j > buffer.Length)
|
if (j >= buffer.Length)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -35,5 +37,55 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(IntegerCodecSamples))]
|
||||||
|
public void EncodeSamples(int value, int bits, byte[] expectedResult)
|
||||||
|
{
|
||||||
|
Span<byte> actualResult = new byte[64];
|
||||||
|
bool success = IntegerEncoder.Encode(value, bits, actualResult, out int bytesWritten);
|
||||||
|
|
||||||
|
Assert.True(success);
|
||||||
|
Assert.Equal(expectedResult.Length, bytesWritten);
|
||||||
|
Assert.True(actualResult.Slice(0, bytesWritten).SequenceEqual(expectedResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(IntegerCodecSamples))]
|
||||||
|
public void EncodeSamplesWithShortBuffer(int value, int bits, byte[] expectedResult)
|
||||||
|
{
|
||||||
|
Span<byte> actualResult = new byte[expectedResult.Length - 1];
|
||||||
|
bool success = IntegerEncoder.Encode(value, bits, actualResult, out int bytesWritten);
|
||||||
|
|
||||||
|
Assert.False(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(IntegerCodecSamples))]
|
||||||
|
public void DecodeSamples(int expectedResult, int bits, byte[] encoded)
|
||||||
|
{
|
||||||
|
var integerDecoder = new IntegerDecoder();
|
||||||
|
|
||||||
|
bool finished = integerDecoder.BeginTryDecode(encoded[0], bits, out int actualResult);
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
for (; !finished && i < encoded.Length; ++i)
|
||||||
|
{
|
||||||
|
finished = integerDecoder.TryDecode(encoded[i], out actualResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.True(finished);
|
||||||
|
Assert.Equal(encoded.Length, i);
|
||||||
|
|
||||||
|
Assert.Equal(expectedResult, actualResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
// integer, prefix length, encoded
|
||||||
|
public static IEnumerable<object[]> IntegerCodecSamples()
|
||||||
|
{
|
||||||
|
yield return new object[] { 10, 5, new byte[] { 0x0A } };
|
||||||
|
yield return new object[] { 1337, 5, new byte[] { 0x1F, 0x9A, 0x0A } };
|
||||||
|
yield return new object[] { 42, 8, new byte[] { 0x2A } };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue