From 0ec79c5196419d03c3d49ca37b0e96eb4fa9a1f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Fri, 12 Jun 2020 10:02:33 -0700 Subject: [PATCH 01/12] Quarantining InputDateInteractsWithEditContext_NonNullableDateTime (#22857) https://github.com/dotnet/aspnetcore-internal/issues/3616 --- src/Components/test/E2ETest/Tests/FormsTest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Components/test/E2ETest/Tests/FormsTest.cs b/src/Components/test/E2ETest/Tests/FormsTest.cs index edd7404f6f..46b6280523 100644 --- a/src/Components/test/E2ETest/Tests/FormsTest.cs +++ b/src/Components/test/E2ETest/Tests/FormsTest.cs @@ -10,6 +10,7 @@ using BasicTestApp.FormsTest; using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; using Microsoft.AspNetCore.E2ETesting; +using Microsoft.AspNetCore.Testing; using OpenQA.Selenium; using OpenQA.Selenium.Support.UI; using Xunit; @@ -190,6 +191,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests } [Fact] + [Flaky("https://github.com/dotnet/aspnetcore-internal/issues/3615", FlakyOn.Helix.All)] public void InputDateInteractsWithEditContext_NonNullableDateTime() { var appElement = MountTypicalValidationComponent(); From dcd1250f43a6d36e074ec5b41216ebb8976aec27 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Fri, 12 Jun 2020 11:10:00 -0700 Subject: [PATCH 02/12] [3.1] Add latin1 support to IIS (#22798) Co-authored-by: Chris Ross --- ...Microsoft.AspNetCore.Server.HttpSys.csproj | 1 + .../IIS/IIS/src/Core/IISHttpContext.cs | 5 +- .../IIS/IIS/src/Core/IISHttpContextOfT.cs | 5 +- src/Servers/IIS/IIS/src/Core/IISHttpServer.cs | 6 +- .../Microsoft.AspNetCore.Server.IIS.csproj | 1 + .../Inprocess/Latin1Tests.cs | 82 +++++++++++++++++++ .../IIS.FunctionalTests.csproj | 3 +- .../IIS.NewHandler.FunctionalTests.csproj | 3 +- .../IIS.NewShim.FunctionalTests.csproj | 3 +- .../IISExpress.FunctionalTests.csproj | 3 +- .../testassets/InProcessWebSite/Program.cs | 23 +++++- .../testassets/InProcessWebSite/Startup.cs | 14 ++++ .../Internal/Infrastructure/HttpUtilities.cs | 61 +------------- ...soft.AspNetCore.Server.Kestrel.Core.csproj | 1 + .../RequestProcessing/HeaderEncoding.cs | 23 +++--- .../RequestProcessing/NativeRequestContext.cs | 13 +-- .../ServerInfrastructure}/StringUtilities.cs | 64 ++++++++++++++- .../Microsoft.AspNetCore.Shared.Tests.csproj | 1 + 18 files changed, 220 insertions(+), 92 deletions(-) create mode 100644 src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/Latin1Tests.cs rename src/{Servers/Kestrel/Core/src/Internal/Infrastructure => Shared/ServerInfrastructure}/StringUtilities.cs (92%) diff --git a/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj b/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj index 06d5ad8b82..d8f520d0d9 100644 --- a/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj +++ b/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs b/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs index 3f7d3c53ce..cb34c49db3 100644 --- a/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs +++ b/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs @@ -74,8 +74,9 @@ namespace Microsoft.AspNetCore.Server.IIS.Core IntPtr pInProcessHandler, IISServerOptions options, IISHttpServer server, - ILogger logger) - : base((HttpApiTypes.HTTP_REQUEST*)NativeMethods.HttpGetRawRequest(pInProcessHandler)) + ILogger logger, + bool useLatin1) + : base((HttpApiTypes.HTTP_REQUEST*)NativeMethods.HttpGetRawRequest(pInProcessHandler), useLatin1: useLatin1) { _memoryPool = memoryPool; _pInProcessHandler = pInProcessHandler; diff --git a/src/Servers/IIS/IIS/src/Core/IISHttpContextOfT.cs b/src/Servers/IIS/IIS/src/Core/IISHttpContextOfT.cs index 372eadfa71..635ed097ea 100644 --- a/src/Servers/IIS/IIS/src/Core/IISHttpContextOfT.cs +++ b/src/Servers/IIS/IIS/src/Core/IISHttpContextOfT.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; @@ -15,8 +16,8 @@ namespace Microsoft.AspNetCore.Server.IIS.Core { private readonly IHttpApplication _application; - public IISHttpContextOfT(MemoryPool memoryPool, IHttpApplication application, IntPtr pInProcessHandler, IISServerOptions options, IISHttpServer server, ILogger logger) - : base(memoryPool, pInProcessHandler, options, server, logger) + public IISHttpContextOfT(MemoryPool memoryPool, IHttpApplication application, IntPtr pInProcessHandler, IISServerOptions options, IISHttpServer server, ILogger logger, bool useLatin1) + : base(memoryPool, pInProcessHandler, options, server, logger, useLatin1) { _application = application; } diff --git a/src/Servers/IIS/IIS/src/Core/IISHttpServer.cs b/src/Servers/IIS/IIS/src/Core/IISHttpServer.cs index ef4c3aabb8..7724f18300 100644 --- a/src/Servers/IIS/IIS/src/Core/IISHttpServer.cs +++ b/src/Servers/IIS/IIS/src/Core/IISHttpServer.cs @@ -214,11 +214,14 @@ namespace Microsoft.AspNetCore.Server.IIS.Core private class IISContextFactory : IISContextFactory { + private const string Latin1Suppport = "Microsoft.AspNetCore.Server.IIS.Latin1RequestHeaders"; + private readonly IHttpApplication _application; private readonly MemoryPool _memoryPool; private readonly IISServerOptions _options; private readonly IISHttpServer _server; private readonly ILogger _logger; + private readonly bool _useLatin1; public IISContextFactory(MemoryPool memoryPool, IHttpApplication application, IISServerOptions options, IISHttpServer server, ILogger logger) { @@ -227,11 +230,12 @@ namespace Microsoft.AspNetCore.Server.IIS.Core _options = options; _server = server; _logger = logger; + AppContext.TryGetSwitch(Latin1Suppport, out _useLatin1); } public IISHttpContext CreateHttpContext(IntPtr pInProcessHandler) { - return new IISHttpContextOfT(_memoryPool, _application, pInProcessHandler, _options, _server, _logger); + return new IISHttpContextOfT(_memoryPool, _application, pInProcessHandler, _options, _server, _logger, _useLatin1); } } } diff --git a/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj b/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj index c645b12741..4f17fcae7a 100644 --- a/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj +++ b/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj @@ -19,6 +19,7 @@ + diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/Latin1Tests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/Latin1Tests.cs new file mode 100644 index 0000000000..646b9c9bd9 --- /dev/null +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/Latin1Tests.cs @@ -0,0 +1,82 @@ +// 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; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities; +using Microsoft.AspNetCore.Server.IntegrationTesting; +using Microsoft.AspNetCore.Server.IntegrationTesting.IIS; +using Microsoft.AspNetCore.Testing; +using Xunit; + +namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess +{ + [Collection(PublishedSitesCollection.Name)] + public class Latin1Tests : IISFunctionalTestBase + { + public Latin1Tests(PublishedSitesFixture fixture) : base(fixture) + { + } + + [ConditionalFact] + [RequiresNewHandler] + public async Task Latin1Works() + { + var deploymentParameters = Fixture.GetBaseDeploymentParameters(); + deploymentParameters.TransformArguments((a, _) => $"{a} AddLatin1"); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var client = new HttpClient(new LoggingHandler(new WinHttpHandler() { SendTimeout = TimeSpan.FromMinutes(3) }, deploymentResult.Logger)); + + var requestMessage = new HttpRequestMessage(HttpMethod.Get, $"{deploymentResult.ApplicationBaseUri}Latin1"); + requestMessage.Headers.Add("foo", "£"); + + var result = await client.SendAsync(requestMessage); + Assert.Equal(HttpStatusCode.OK, result.StatusCode); + } + + [ConditionalFact] + [RequiresNewHandler] + public async Task Latin1ReplacedWithoutAppContextSwitch() + { + var deploymentParameters = Fixture.GetBaseDeploymentParameters(); + deploymentParameters.TransformArguments((a, _) => $"{a}"); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var client = new HttpClient(new LoggingHandler(new WinHttpHandler() { SendTimeout = TimeSpan.FromMinutes(3) }, deploymentResult.Logger)); + + var requestMessage = new HttpRequestMessage(HttpMethod.Get, $"{deploymentResult.ApplicationBaseUri}InvalidCharacter"); + requestMessage.Headers.Add("foo", "£"); + + var result = await client.SendAsync(requestMessage); + Assert.Equal(HttpStatusCode.OK, result.StatusCode); + } + + [ConditionalFact] + [RequiresNewHandler] + public async Task Latin1InvalidCharacters_HttpSysRejects() + { + var deploymentParameters = Fixture.GetBaseDeploymentParameters(); + deploymentParameters.TransformArguments((a, _) => $"{a} AddLatin1"); + + var deploymentResult = await DeployAsync(deploymentParameters); + + using (var connection = new TestConnection(deploymentResult.HttpClient.BaseAddress.Port)) + { + await connection.Send( + "GET /ReadAndFlushEcho HTTP/1.1", + "Host: localhost", + "Connection: close", + "foo: £\0a", + "", + ""); + + await connection.ReceiveStartsWith("HTTP/1.1 400 Bad Request"); + } + } + } +} diff --git a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj index a7858c63b2..202138392d 100644 --- a/src/Servers/IIS/IIS/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj +++ b/src/Servers/IIS/IIS/test/IIS.FunctionalTests/IIS.FunctionalTests.csproj @@ -1,4 +1,4 @@ - + @@ -27,6 +27,7 @@ + diff --git a/src/Servers/IIS/IIS/test/IIS.NewHandler.FunctionalTests/IIS.NewHandler.FunctionalTests.csproj b/src/Servers/IIS/IIS/test/IIS.NewHandler.FunctionalTests/IIS.NewHandler.FunctionalTests.csproj index 9a74ecd31d..7c4f552cc3 100644 --- a/src/Servers/IIS/IIS/test/IIS.NewHandler.FunctionalTests/IIS.NewHandler.FunctionalTests.csproj +++ b/src/Servers/IIS/IIS/test/IIS.NewHandler.FunctionalTests/IIS.NewHandler.FunctionalTests.csproj @@ -1,4 +1,4 @@ - + $(DefaultNetCoreTargetFramework) @@ -34,6 +34,7 @@ + diff --git a/src/Servers/IIS/IIS/test/IIS.NewShim.FunctionalTests/IIS.NewShim.FunctionalTests.csproj b/src/Servers/IIS/IIS/test/IIS.NewShim.FunctionalTests/IIS.NewShim.FunctionalTests.csproj index 03adce1d09..56f95d8ec1 100644 --- a/src/Servers/IIS/IIS/test/IIS.NewShim.FunctionalTests/IIS.NewShim.FunctionalTests.csproj +++ b/src/Servers/IIS/IIS/test/IIS.NewShim.FunctionalTests/IIS.NewShim.FunctionalTests.csproj @@ -1,4 +1,4 @@ - + $(DefaultNetCoreTargetFramework) @@ -28,6 +28,7 @@ + diff --git a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj index 23a5ecdf71..8615b70c3d 100644 --- a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj +++ b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/IISExpress.FunctionalTests.csproj @@ -1,4 +1,4 @@ - + @@ -30,6 +30,7 @@ + diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Program.cs b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Program.cs index 4b9889a141..0132efc2e7 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Program.cs +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Program.cs @@ -145,9 +145,9 @@ namespace TestSite } return 0; +#if !FORWARDCOMPAT case "ThrowInStartupGenericHost": { -#if !FORWARDCOMPAT var host = new HostBuilder().ConfigureWebHost((c) => { c.ConfigureLogging((_, factory) => @@ -161,9 +161,26 @@ namespace TestSite host.Build().Run(); -#endif + return 0; } - return 0; + case "AddLatin1": + { + AppContext.SetSwitch("Microsoft.AspNetCore.Server.IIS.Latin1RequestHeaders", isEnabled: true); + var host = new HostBuilder().ConfigureWebHost((c) => + { + c.ConfigureLogging((_, factory) => + { + factory.AddConsole(); + factory.AddFilter("Console", level => level >= LogLevel.Information); + }) + .UseIIS() + .UseStartup(); + }); + + host.Build().Run(); + return 0; + } +#endif default: return StartServer(); diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs index 7336dda665..ef9f8758b5 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs @@ -1005,5 +1005,19 @@ namespace TestSite await context.Response.WriteAsync(httpsPort.HasValue ? httpsPort.Value.ToString() : "NOVALUE"); } + + public Task Latin1(HttpContext context) + { + var value = context.Request.Headers["foo"]; + Assert.Equal("£", value); + return Task.CompletedTask; + } + + public Task InvalidCharacter(HttpContext context) + { + var value = context.Request.Headers["foo"]; + Assert.Equal("�", value); + return Task.CompletedTask; + } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs index 04fd9711d7..121be08041 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs @@ -130,67 +130,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure return asciiString; } - private static unsafe string GetAsciiOrUTF8StringNonNullCharacters(this Span span) - { - if (span.IsEmpty) - { - return string.Empty; - } - - var resultString = new string('\0', span.Length); - - fixed (char* output = resultString) - fixed (byte* buffer = span) - { - // StringUtilities.TryGetAsciiString returns null if there are any null (0 byte) characters - // in the string - if (!StringUtilities.TryGetAsciiString(buffer, output, span.Length)) - { - // null characters are considered invalid - if (span.IndexOf((byte)0) != -1) - { - throw new InvalidOperationException(); - } - - try - { - resultString = HeaderValueEncoding.GetString(buffer, span.Length); - } - catch (DecoderFallbackException) - { - throw new InvalidOperationException(); - } - } - } - - return resultString; - } - - private static unsafe string GetLatin1StringNonNullCharacters(this Span span) - { - if (span.IsEmpty) - { - return string.Empty; - } - - var resultString = new string('\0', span.Length); - - fixed (char* output = resultString) - fixed (byte* buffer = span) - { - // This returns false if there are any null (0 byte) characters in the string. - if (!StringUtilities.TryGetLatin1String(buffer, output, span.Length)) - { - // null characters are considered invalid - throw new InvalidOperationException(); - } - } - - return resultString; - } - public static string GetRequestHeaderStringNonNullCharacters(this Span span, bool useLatin1) => - useLatin1 ? GetLatin1StringNonNullCharacters(span) : GetAsciiOrUTF8StringNonNullCharacters(span); + useLatin1 ? span.GetLatin1StringNonNullCharacters() : span.GetAsciiOrUTF8StringNonNullCharacters(HeaderValueEncoding); public static string GetAsciiStringEscaped(this Span span, int maxChars) { diff --git a/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj b/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj index 6c18f1a078..98283fec77 100644 --- a/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj +++ b/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Shared/HttpSys/RequestProcessing/HeaderEncoding.cs b/src/Shared/HttpSys/RequestProcessing/HeaderEncoding.cs index 991571904b..085ed7d7ed 100644 --- a/src/Shared/HttpSys/RequestProcessing/HeaderEncoding.cs +++ b/src/Shared/HttpSys/RequestProcessing/HeaderEncoding.cs @@ -1,29 +1,26 @@ // 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; using System.Text; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; namespace Microsoft.AspNetCore.HttpSys.Internal { internal static class HeaderEncoding { - // It should just be ASCII or ANSI, but they break badly with un-expected values. We use UTF-8 because it's the same for - // ASCII, and because some old client would send UTF8 Host headers and expect UTF8 Location responses - // (e.g. IE and HttpWebRequest on intranets). - private static Encoding Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false); + private static readonly Encoding Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false); - internal static unsafe string GetString(byte* pBytes, int byteCount) + internal static unsafe string GetString(byte* pBytes, int byteCount, bool useLatin1) { - // net451: return new string(pBytes, 0, byteCount, Encoding); - - var charCount = Encoding.GetCharCount(pBytes, byteCount); - var chars = new char[charCount]; - fixed (char* pChars = chars) + if (useLatin1) { - var count = Encoding.GetChars(pBytes, byteCount, pChars, charCount); - System.Diagnostics.Debug.Assert(count == charCount); + return new Span(pBytes, byteCount).GetLatin1StringNonNullCharacters(); + } + else + { + return new Span(pBytes, byteCount).GetAsciiOrUTF8StringNonNullCharacters(Encoding); } - return new string(chars); } internal static byte[] GetBytes(string myString) diff --git a/src/Shared/HttpSys/RequestProcessing/NativeRequestContext.cs b/src/Shared/HttpSys/RequestProcessing/NativeRequestContext.cs index 4108d901e2..f44fa0c4ec 100644 --- a/src/Shared/HttpSys/RequestProcessing/NativeRequestContext.cs +++ b/src/Shared/HttpSys/RequestProcessing/NativeRequestContext.cs @@ -18,6 +18,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal { private const int AlignmentPadding = 8; private IntPtr _originalBufferAddress; + private bool _useLatin1; private HttpApiTypes.HTTP_REQUEST* _nativeRequest; private byte[] _backingBuffer; private int _bufferAlignment; @@ -39,8 +40,9 @@ namespace Microsoft.AspNetCore.HttpSys.Internal } // To be used by IIS Integration. - internal NativeRequestContext(HttpApiTypes.HTTP_REQUEST* request) + internal NativeRequestContext(HttpApiTypes.HTTP_REQUEST* request, bool useLatin1) { + _useLatin1 = useLatin1; _nativeRequest = request; _bufferAlignment = 0; _permanentlyPinned = true; @@ -125,7 +127,8 @@ namespace Microsoft.AspNetCore.HttpSys.Internal } else if (verb == HttpApiTypes.HTTP_VERB.HttpVerbUnknown && NativeRequest->pUnknownVerb != null) { - return HeaderEncoding.GetString(NativeRequest->pUnknownVerb, NativeRequest->UnknownVerbLength); + // Never use Latin1 for the VERB + return HeaderEncoding.GetString(NativeRequest->pUnknownVerb, NativeRequest->UnknownVerbLength, useLatin1: false); } return null; @@ -291,7 +294,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal // pRawValue will point to empty string ("\0") if (pKnownHeader->RawValueLength > 0) { - value = HeaderEncoding.GetString(pKnownHeader->pRawValue + fixup, pKnownHeader->RawValueLength); + value = HeaderEncoding.GetString(pKnownHeader->pRawValue + fixup, pKnownHeader->RawValueLength, _useLatin1); } return value; @@ -329,11 +332,11 @@ namespace Microsoft.AspNetCore.HttpSys.Internal // pRawValue will be null. if (pUnknownHeader->pName != null && pUnknownHeader->NameLength > 0) { - var headerName = HeaderEncoding.GetString(pUnknownHeader->pName + fixup, pUnknownHeader->NameLength); + var headerName = HeaderEncoding.GetString(pUnknownHeader->pName + fixup, pUnknownHeader->NameLength, _useLatin1); string headerValue; if (pUnknownHeader->pRawValue != null && pUnknownHeader->RawValueLength > 0) { - headerValue = HeaderEncoding.GetString(pUnknownHeader->pRawValue + fixup, pUnknownHeader->RawValueLength); + headerValue = HeaderEncoding.GetString(pUnknownHeader->pRawValue + fixup, pUnknownHeader->RawValueLength, _useLatin1); } else { diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/StringUtilities.cs b/src/Shared/ServerInfrastructure/StringUtilities.cs similarity index 92% rename from src/Servers/Kestrel/Core/src/Internal/Infrastructure/StringUtilities.cs rename to src/Shared/ServerInfrastructure/StringUtilities.cs index 268d77a0e4..0dfdf45ade 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/StringUtilities.cs +++ b/src/Shared/ServerInfrastructure/StringUtilities.cs @@ -11,8 +11,67 @@ using System.Text; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure { - internal class StringUtilities + internal static class StringUtilities { + public static unsafe string GetAsciiOrUTF8StringNonNullCharacters(this Span span, Encoding defaultEncoding) + { + if (span.IsEmpty) + { + return string.Empty; + } + + var resultString = new string('\0', span.Length); + + fixed (char* output = resultString) + fixed (byte* buffer = span) + { + // StringUtilities.TryGetAsciiString returns null if there are any null (0 byte) characters + // in the string + if (!TryGetAsciiString(buffer, output, span.Length)) + { + // null characters are considered invalid + if (span.IndexOf((byte)0) != -1) + { + throw new InvalidOperationException(); + } + + try + { + resultString = defaultEncoding.GetString(buffer, span.Length); + } + catch (DecoderFallbackException) + { + throw new InvalidOperationException(); + } + } + } + + return resultString; + } + + public static unsafe string GetLatin1StringNonNullCharacters(this Span span) + { + if (span.IsEmpty) + { + return string.Empty; + } + + var resultString = new string('\0', span.Length); + + fixed (char* output = resultString) + fixed (byte* buffer = span) + { + // This returns false if there are any null (0 byte) characters in the string. + if (!TryGetLatin1String(buffer, output, span.Length)) + { + // null characters are considered invalid + throw new InvalidOperationException(); + } + } + + return resultString; + } + [MethodImpl(MethodImplOptions.AggressiveOptimization)] public static unsafe bool TryGetAsciiString(byte* input, char* output, int count) { @@ -472,7 +531,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true).GetByteCount(value); return !value.Contains('\0'); } - catch (DecoderFallbackException) { + catch (DecoderFallbackException) + { return false; } } diff --git a/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj b/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj index 83fe4babb7..fde501c508 100644 --- a/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj +++ b/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj @@ -16,6 +16,7 @@ + From 8dce53054a70409a60770c5f1bf442daa6b79ebb Mon Sep 17 00:00:00 2001 From: Brady Gaster <41929050+bradygaster@users.noreply.github.com> Date: Fri, 12 Jun 2020 16:19:53 -0700 Subject: [PATCH 03/12] updating signalr js package readme (#22129) * updating signalr js package readme * Update src/SignalR/clients/ts/signalr/README.md Co-authored-by: Brennan * Update PatchConfig.props Co-authored-by: Brennan --- eng/PatchConfig.props | 1 + src/SignalR/clients/ts/signalr/README.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/eng/PatchConfig.props b/eng/PatchConfig.props index 0fa48bac75..aefa226d15 100644 --- a/eng/PatchConfig.props +++ b/eng/PatchConfig.props @@ -63,6 +63,7 @@ Later on, this will be checked using this condition: + @aspnet/signalr; diff --git a/src/SignalR/clients/ts/signalr/README.md b/src/SignalR/clients/ts/signalr/README.md index 4a15d4eb6c..8015ef00da 100644 --- a/src/SignalR/clients/ts/signalr/README.md +++ b/src/SignalR/clients/ts/signalr/README.md @@ -1,5 +1,7 @@ JavaScript and TypeScript clients for SignalR for ASP.NET Core +> Note: The JavaScript and TypeScript clients for SignalR for ASP.NET Core have been moved to [@microsoft/signalr](https://www.npmjs.com/package/@microsoft/signalr). If you are already using `@aspnet/signalr` and are unsure when to move to `@microsoft/signalr`, check the [Feature Distribution](https://docs.microsoft.com/en-us/aspnet/core/signalr/client-features) chart in the ASP.NET Core SignalR documentation. Newer client releases are compatible with older version of ASP.NET Core SignalR which means it is safe to upgrade the client before upgrading the server. + ## Installation ```bash From 350540d0af123f4ffcc479308aff75d4e5364620 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Fri, 12 Jun 2020 16:30:28 -0700 Subject: [PATCH 04/12] Make WebAssembly templates use the same version as the rest of the WASM product (#22896) We've already shipped a 3.2.0 version of the package. The build's currently producing 3.1.6 version of the package. This changes the package version to 3.2.1 --- .../Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj b/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj index 0c899f5f13..efde20de6d 100644 --- a/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj +++ b/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj @@ -8,6 +8,7 @@ true Templates for ASP.NET Core Blazor WebAssembly projects. $(PackageTags);blazor;spa + $(ComponentsWebAssemblyVersionPrefix) From 9288627fededcc2eb2bab2ff419b5a58dcea6d7d Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 15 Jun 2020 13:31:09 -0700 Subject: [PATCH 05/12] Fixing up build issues --- .../src/Microsoft.AspNetCore.Server.HttpSys.csproj | 1 + .../Core/src/Internal/Infrastructure/HttpUtilities.cs | 8 +++++++- .../src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj | 5 ++--- src/Shared/Http2cat/Http2Utilities.cs | 2 +- src/Shared/ServerInfrastructure/StringUtilities.cs | 7 ++----- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj b/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj index 501aa01125..dabe46a33b 100644 --- a/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj +++ b/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs index 39f38b4e21..ede9d52e2e 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs @@ -120,6 +120,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure } } + public static string GetAsciiOrUTF8StringNonNullCharacters(this Span span) + => GetAsciiOrUTF8StringNonNullCharacters((ReadOnlySpan)span); + + public static string GetAsciiOrUTF8StringNonNullCharacters(this ReadOnlySpan span) + => StringUtilities.GetAsciiOrUTF8StringNonNullCharacters(span, HeaderValueEncoding); + private static unsafe void GetAsciiStringNonNullCharacters(Span buffer, IntPtr state) { fixed (char* output = &MemoryMarshal.GetReference(buffer)) @@ -133,7 +139,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure } } - public static string GetRequestHeaderStringNonNullCharacters(this Span span, bool useLatin1) => + public static string GetRequestHeaderStringNonNullCharacters(this ReadOnlySpan span, bool useLatin1) => useLatin1 ? span.GetLatin1StringNonNullCharacters() : span.GetAsciiOrUTF8StringNonNullCharacters(HeaderValueEncoding); public static string GetAsciiStringEscaped(this ReadOnlySpan span, int maxChars) diff --git a/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj b/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj index 59c2a87e41..5694b9d2b7 100644 --- a/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj +++ b/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj @@ -1,4 +1,4 @@ - + Core components of ASP.NET Core Kestrel cross-platform web server. @@ -20,9 +20,8 @@ - - + diff --git a/src/Shared/Http2cat/Http2Utilities.cs b/src/Shared/Http2cat/Http2Utilities.cs index b320850eaa..0cc3a77cf3 100644 --- a/src/Shared/Http2cat/Http2Utilities.cs +++ b/src/Shared/Http2cat/Http2Utilities.cs @@ -168,7 +168,7 @@ namespace Microsoft.AspNetCore.Http2Cat return asciiString; } - public unsafe string GetAsciiOrUTF8StringNonNullCharacters(ReadOnlySpan span) + public unsafe string GetAsciiOrUTF8StringNonNullCharacters(this ReadOnlySpan span) { if (span.IsEmpty) { diff --git a/src/Shared/ServerInfrastructure/StringUtilities.cs b/src/Shared/ServerInfrastructure/StringUtilities.cs index 0d556f9fe4..8f6b01027a 100644 --- a/src/Shared/ServerInfrastructure/StringUtilities.cs +++ b/src/Shared/ServerInfrastructure/StringUtilities.cs @@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure internal static class StringUtilities { private static string GetAsciiOrUTF8StringNonNullCharacters(this Span span, Encoding defaultEncoding) - => GetAsciiOrUTF8StringNonNullCharacters((ReadOnlySpan)span); + => GetAsciiOrUTF8StringNonNullCharacters((ReadOnlySpan)span, defaultEncoding); public static unsafe string GetAsciiOrUTF8StringNonNullCharacters(this ReadOnlySpan span, Encoding defaultEncoding) { @@ -50,11 +50,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure return resultString; } - - return resultString; } - private static readonly SpanAction s_getAsciiOrUtf8StringNonNullCharacters = GetAsciiOrUTF8StringNonNullCharacters; private static unsafe void GetAsciiOrUTF8StringNonNullCharacters(Span buffer, IntPtr state) @@ -71,7 +68,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure } } - public static unsafe string GetLatin1StringNonNullCharacters(this Span span) + public static unsafe string GetLatin1StringNonNullCharacters(this ReadOnlySpan span) { if (span.IsEmpty) { From 122cf4ee4c09c5a6d688a8861ac121aa34f22617 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 15 Jun 2020 14:03:18 -0700 Subject: [PATCH 06/12] Delete Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj --- ...re.Components.WebAssembly.Templates.csproj | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj diff --git a/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj b/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj deleted file mode 100644 index efde20de6d..0000000000 --- a/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj +++ /dev/null @@ -1,49 +0,0 @@ - - - $(RepoRoot)src\Components\WebAssembly\ - - - - $(DefaultNetCoreTargetFramework) - true - Templates for ASP.NET Core Blazor WebAssembly projects. - $(PackageTags);blazor;spa - $(ComponentsWebAssemblyVersionPrefix) - - - - - - DefaultNetCoreTargetFramework=$(DefaultNetCoreTargetFramework); - MicrosoftEntityFrameworkCoreSqlServerPackageVersion=$(MicrosoftEntityFrameworkCoreSqlServerPackageVersion); - MicrosoftEntityFrameworkCoreSqlitePackageVersion=$(MicrosoftEntityFrameworkCoreSqlitePackageVersion); - MicrosoftEntityFrameworkCoreToolsPackageVersion=$(MicrosoftEntityFrameworkCoreToolsPackageVersion); - MicrosoftExtensionsHttpPackageVersion=$(MicrosoftExtensionsHttpPackageVersion); - SystemNetHttpJsonPackageVersion=$(SystemNetHttpJsonPackageVersion) - - - - - - - - - - - - - - - - - - - - - - - - - - - From dc3cb10f2bf0058c53e81efbdc90b4888e75d30b Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 15 Jun 2020 16:31:32 -0700 Subject: [PATCH 07/12] Update Microsoft.AspNetCore.Shared.Tests.csproj --- .../test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj b/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj index 43f275a361..03644c3e24 100644 --- a/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj +++ b/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj @@ -31,6 +31,7 @@ + @@ -60,4 +61,4 @@ - \ No newline at end of file + From bccaa41ca8a65a1c939b428005026aec8062d70b Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 17 Jun 2020 11:17:35 -0700 Subject: [PATCH 08/12] Update Http2Utilities.cs --- src/Shared/Http2cat/Http2Utilities.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Shared/Http2cat/Http2Utilities.cs b/src/Shared/Http2cat/Http2Utilities.cs index 0cc3a77cf3..b320850eaa 100644 --- a/src/Shared/Http2cat/Http2Utilities.cs +++ b/src/Shared/Http2cat/Http2Utilities.cs @@ -168,7 +168,7 @@ namespace Microsoft.AspNetCore.Http2Cat return asciiString; } - public unsafe string GetAsciiOrUTF8StringNonNullCharacters(this ReadOnlySpan span) + public unsafe string GetAsciiOrUTF8StringNonNullCharacters(ReadOnlySpan span) { if (span.IsEmpty) { From b8de65dbac52315efb89308c0ecf71c80065013c Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 17 Jun 2020 11:18:22 -0700 Subject: [PATCH 09/12] Update Microsoft.AspNetCore.Shared.Tests.csproj --- .../Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj b/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj index 03644c3e24..5ec4559848 100644 --- a/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj +++ b/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj @@ -59,6 +59,10 @@ System.Net.Http.SR + + Microsoft.AspNetCore.Server.SharedStrings + + From c5b7eab3454f65ce9bb54c21666ae0c7b9683cf8 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 17 Jun 2020 13:53:19 -0700 Subject: [PATCH 10/12] Update Microsoft.AspNetCore.Server.HttpSys.csproj --- .../HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj b/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj index dabe46a33b..72b994fff3 100644 --- a/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj +++ b/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj @@ -14,7 +14,7 @@ - + From 855a73816d6840750083da65db556122620e2da4 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Wed, 17 Jun 2020 13:54:53 -0700 Subject: [PATCH 11/12] Update Microsoft.AspNetCore.Server.HttpSys.FunctionalTests.csproj --- .../Microsoft.AspNetCore.Server.HttpSys.FunctionalTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/HttpSys/test/FunctionalTests/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests.csproj b/src/Servers/HttpSys/test/FunctionalTests/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests.csproj index d0a2c7558b..789ce6e844 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests.csproj +++ b/src/Servers/HttpSys/test/FunctionalTests/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests.csproj @@ -12,7 +12,7 @@ - + From cbb8c6d915aaa62faf922fafaf490c2cdcc480fb Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Thu, 18 Jun 2020 09:48:40 -0700 Subject: [PATCH 12/12] Update FormsTest.cs --- src/Components/test/E2ETest/Tests/FormsTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/test/E2ETest/Tests/FormsTest.cs b/src/Components/test/E2ETest/Tests/FormsTest.cs index 4bdfcb78b8..b573a5bd85 100644 --- a/src/Components/test/E2ETest/Tests/FormsTest.cs +++ b/src/Components/test/E2ETest/Tests/FormsTest.cs @@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests } [Fact] - [Flaky("https://github.com/dotnet/aspnetcore-internal/issues/3615", FlakyOn.Helix.All)] + [QuarantinedTest("https://github.com/dotnet/aspnetcore-internal/issues/3615")] public void InputDateInteractsWithEditContext_NonNullableDateTime() { var appElement = MountTypicalValidationComponent();